DoubleP90
DoubleP90

Reputation: 1249

How to kill a thread in a service?

I have a service that runs whenever the screen gets turned on. When I put the phone to sleep, the service and the thread should stop.

I managed to stop the service, but the thread still runs. How can i kill the thread?

void runAppCheck(){
    new Thread(new Runnable() {
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while (true) {
                try {
                    Thread.sleep(10000);
                    mHandler.post(new Runnable() {

                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            getForegroundApplication();
                            compareResults();
                            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
                            boolean screenIsOn = pm.isScreenOn();
                            if (!screenIsOn) {
                                Log.i(TAG ,"Screen is OFF, stopping service");
                                stopSelf();
                                //TODO stop thread
                            }
                        }
                    });
                } catch (Exception e) {
                    // TODO: handle exception
                }
            }
        }
    }).start();

Upvotes: 1

Views: 621

Answers (2)

Streets Of Boston
Streets Of Boston

Reputation: 12596

I don't get your problem entirely, because the answer seem to be quite easy, unless I'm missing something.

Stopping your thread in your example seems to be as easy as calling return;, which will end the public void run() method and that will end the thread.

      ....
                       if (!screenIsOn) {
                            Log.i(TAG ,"Screen is OFF, stopping service");
                            stopSelf();
                            return;
                        }
      ....

Update after OP's comment:

If you are not using an AlarmManager and you can be sure that your thread still receives some CPU cycles, why do you do a mHandler.post(....) call? Why not just skip that post call.

void runAppCheck(){
new Thread(new Runnable() {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (true) {
            try {
                Thread.sleep(10000);
                        // TODO Auto-generated method stub
                        getForegroundApplication();
                        compareResults();
                        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
                        boolean screenIsOn = pm.isScreenOn();
                        if (!screenIsOn) {
                            Log.i(TAG ,"Screen is OFF, stopping service");
                            stopSelf();

                            //stop thread
                            return;
                        }
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }
}).start();

Upvotes: 0

Trevor
Trevor

Reputation: 10993

You can stop a Thread by using a shared variable that acts as a flag to ask the Thread to stop. For example, in your outer Thread, declare private volatile boolean mRunning = true and change tn the outer while(true) to while(mRunning). Then implement a method to request it to cease running:

public void terminate() {
    mRunning = false;
}

Upvotes: 1

Related Questions