Pratik Butani
Pratik Butani

Reputation: 62419

Service with Timer calling another Service

I am managing data from Server to Client and Client to Server using Service. In that I am calling one Service after Login:

context.startService(new Intent(LoginActivity.this, CheckAutoSyncReceivingOrder.class));
context.startService(new Intent(LoginActivity.this, CheckAutoSyncSendingOrder.class));

I have called one timer in above both Service

CheckAutoSyncReceivingOrder Service:

Its calling another service named ReceivingOrderService on Every 1 minute to get updated data from server.

public class CheckAutoSyncReceivingOrder extends Service {

    Timer timer;

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "CheckAutoSyncReceivingOrder Binding Service...");
        return null;
    }

    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub

        if (timer != null) {
            timer.cancel();
            Log.i(TAG, "RECEIVING OLD TIMER CANCELLED>>>");
        }

        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Log.i(TAG, "<<<<<<<<< RECEIVING AUTO SYNC SERVICE <<<<<<<<");
                if (InternetConnection.checkConnection(getApplicationContext())) {
                    if (getDatabasePath(DatabaseHelper.DATABASE_NAME).exists())
                        startService(new Intent(
                                CheckAutoSyncReceivingOrder.this,
                                ReceivingOrderService.class));
                } else {
                    Log.d(TAG, "Connection not available");
                }
            }
        }, 0, 60000); // 1000*60 = 60000 = 1 minutes
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub

        if (timer != null)
            timer.cancel();

        Log.d(TAG, "Stopping Receiving...");

        super.onDestroy();
    }
}

CheckAutoSyncSendingOrder Service:

Its calling another service named SendingOrderService on Every 2.5 minute to send updated data to server.

public class CheckAutoSyncSendingOrder extends Service {

    Timer timer;

    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub

        if (timer != null) {
            timer.cancel();
            Log.i(TAG, "OLD TIMER CANCELLED>>>");
        }

        timer = new Timer();

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Log.i(TAG, ">>>>>>>> SENDING AUTO SYNC SERVICE >>>>>>>>");
                if (InternetConnection.checkConnection(getApplicationContext())) {
                    if (getDatabasePath(DatabaseHelper.DATABASE_NAME).exists())
                        startService(new Intent(CheckAutoSyncSendingOrder.this,
                                SendingOrderService.class));
                } else {
                    Log.d(TAG, "connection not available");
                }
            }
        }, 0, 150000); // 1000*60 = 60000 = 1 minutes * 2.5 = 2.5 =>Minutes
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub

        if (timer != null)
            timer.cancel();

        Log.d(TAG, "Stopping Sending...");

        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

Both Activity will running till Internet off. It will automatically call again when Internet Connection Available.

Main thing is I am getting problem While destroying activity services calls automatically.

Is there any solution or way to change flow for same thing?

Advance Thanking you.

Upvotes: 3

Views: 1154

Answers (2)

Rajesh Jadav
Rajesh Jadav

Reputation: 12861

You have to use IntentService instead of Service.

  • The Service runs in background but it runs on the Main Thread of the application.
  • The IntentService runs on a separate worker thread.

If the process that runs your service gets killed, the Android system will restart it automatically it is default behavior.

so if Activity's Main thread is destroyed service will restart but if you use IntentService and use START_NOT_STICKY then it will not restart your services.

This behavior is defined by the return value of onStartCommand() in your Service implementation. The constant START_NOT_STICKY tells Android not to restart the service if it s running while the process is "killed".

You need to Override method onStartCommand() in your service class and move all your code from onStart() method to onStartCommand() method.

According to the Android Documentation:

For started services, there are two additional major modes of operation they can decide to run in, depending on the value they return from onStartCommand(): START_STICKY is used for services that are explicitly started and stopped as needed, while START_NOT_STICKY or START_REDELIVER_INTENT are used for services that should only remain running while processing any commands sent to them

onStart() method calls each time when service is restarted but onStartCommand() method will not called if you return START_NON_STICKY.

For more details of difference between IntentService and Service. you can check this.

I hope this helps you.

Upvotes: 2

Onik
Onik

Reputation: 19979

From the documentation:

When a service is started, it has a lifecycle that's independent of the component that started it and the service can run in the background indefinitely, even if the component that started it is destroyed. As such, the service should stop itself when its job is done by calling stopSelf(), or another component can stop it by calling stopService().

Since you "dont have overrides any other methods excepting onCreate()" in the Activity in question, you might experience the following:

  1. Service's onDestroy() won't be called unless another app component call stopService();
  2. that said results in Timer keep executing its job.

Stop the services as per the documentation.

Edit (with respect to your comment):

"its starting new job when i destroy activity" means the system killed the service and, since you haven't overridden onStartCommand() whose default return value is START_STICKY, the service has been recreated and its onStart() method has been called.

You cannot change such a system behaviour. But you can run the service in foreground.

Upvotes: 2

Related Questions