Mohammed Ali
Mohammed Ali

Reputation: 2926

Handler and Thread inside Service keeps running, while the Service seems to have stopped

I have a Service that uses Handler and Thread to run some code every 5 seconds. When I call stopSelf() the service seems to have stopped, because from the device Setting -> Apps -> Running it doesn't show there. But the code inside the thread keeps on running every 5 seconds, although i have stopped the service.
Why is the Handler and Thread alive even when the service has stopped? How do i stop the Handler and Thread, when the service has stopped.

final Handler h = new Handler();
final int delay = 5000; // milliseconds

h.postDelayed(new Runnable() {
        public void run() {
            // do something
            final SharedPreferences sharedPref = getSharedPreferences(
                    getString(R.string.prefs), Context.MODE_PRIVATE);
            if (sharedPref != null) {

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // SOME CODE
                        Log.d("UPDATING"," something here");
                        isUpdated = updateToServer(data);
                        if(isUpdated) {
                            sharedPref.edit().putBoolean("updated",true).commit();
                            stopSelf();
                        }
                    }
                }).start();
            }
            h.postDelayed(this, delay);
        }
    }, delay);

Upvotes: 3

Views: 3561

Answers (3)

miselking
miselking

Reputation: 3083

As the name suggests, the Thread run separately from Service so it won't stop just by stopping the service. I didn't actually test this code but it should stop your thread and handler, or give you the general idea how to do it.

final Handler h = new Handler();
final int delay = 5000; // milliseconds
private boolean isRunning = true;  // a variable to signal stopping the thread

h.postDelayed(new Runnable() {
    public void run() {
        // do something
        final SharedPreferences sharedPref = getSharedPreferences(
                getString(R.string.prefs), Context.MODE_PRIVATE);
        if (sharedPref != null) {

            new Thread(new Runnable() {
                @Override
                public void run() {
                  if (isRunning) {
                    // SOME CODE
                    Log.d("UPDATING"," something here");
                    isUpdated = updateToServer(data);
                    if(isUpdated) {
                        sharedPref.edit().putBoolean("updated",true).commit();
                        isRunning = false;  // used to stop the thread from continuing the work
                        h.removeCallbacks(this);  // stopping handler ("this" is the handler runnable you are stopping)
                        stopSelf();
                    }
                  }
                }
            }).start();
        }
        h.postDelayed(this, delay);
    }
}, delay);

Hope this helps you...

Upvotes: 1

Lei Guo
Lei Guo

Reputation: 2550

You should verify isUpdated before posting Runnable, if isUpdated==true, don't post again, code as following:

final Handler h = new Handler();
final int delay = 5000; // milliseconds

h.postDelayed(new Runnable() {
        public void run() {
            // do something
            final SharedPreferences sharedPref = getSharedPreferences(
                    getString(R.string.prefs), Context.MODE_PRIVATE);
            if (sharedPref != null) {

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // SOME CODE
                        Log.d("UPDATING"," something here");
                        isUpdated = updateToServer(data);
                        if(isUpdated) {
                            sharedPref.edit().putBoolean("updated",true).commit();
                            stopSelf();
                        }
                    }
                }).start();
            }
            if(!isUpdated){
               h.postDelayed(this, delay);
            }

        }
    }, delay);

Upvotes: 2

Ze Luis
Ze Luis

Reputation: 236

I think you have to call myHandler.getLooper().quit() before stopping the service.

Upvotes: 0

Related Questions