Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onDestroy being called but service not ending

I'm following the book 'Beginning Android 4 Development', and I'm controlling a service using the following functions from buttons:

public void startService(View view) {
    startService(new Intent(getBaseContext(), QOLService.class));
}

public void stopService(View view) {
    stopService(new Intent(getBaseContext(), QOLService.class));
}

QOLService.java includes

public class QOLService extends Service {

    int counter = 0;

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //Keep running service until stopped, so return sticky
        Timer timer=new Timer();
        TimerTask tt =new TimerTask() {
            @Override
            public void run() {
                Log.d("QOLService", String.valueOf(++counter));
                }
        };

        timer.scheduleAtFixedRate(tt, 0, 1000);

        Toast.makeText(this, "Service started", Toast.LENGTH_LONG).show();
        return START_STICKY;
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "Service destroyed", Toast.LENGTH_LONG).show();
    }

As intended, on pressing the start button I get the 'service started' toast, and in logcat I get a message incrementing every second. This continues, as intended, even when the application is closed.

When I click the stopservice button, I also get the expected 'service destroyed' message, but the timer lives on! If I close the application it still keeps going. If I click the stopservice button again, it does NOT given the service destroyed message, as if it had been successfully destroyed the first time.

Am I calling my timer inappropriately? If so, I seem to be doing it exactly as the book advises!

like image 690
James Avatar asked Dec 21 '22 17:12

James


2 Answers

Am I calling my timer inappropriately?

You are never stopping the timer. Hence, it will keep running until the process is terminated. You should stop the timer in onDestroy().

like image 74
CommonsWare Avatar answered Jan 03 '23 05:01

CommonsWare


I am agree with CommonsWare, You haven't stop your timer in the code. I suggest you to go this way,

public class QOLService extends Service {

    int counter = 0;
    Timer timer;
    TimerTask tt;

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //Keep running service until stopped, so return sticky
        timer=new Timer();
        tt =new TimerTask() {
            @Override
            public void run() {
                Log.d("QOLService", String.valueOf(++counter));
                }
        };

        timer.scheduleAtFixedRate(tt, 0, 1000);

        Toast.makeText(this, "Service started", Toast.LENGTH_LONG).show();
        return START_STICKY;
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "Service destroyed", Toast.LENGTH_LONG).show();
        tt.cancel();
        timer.cancel();
    }
}

The cancel() method will stop your Timer as well as.

like image 40
Lucifer Avatar answered Jan 03 '23 04:01

Lucifer