标签: thread

  • Handler and Activity’s life cycle, take care about orphan threads!!

    http://android2ee.blogspot.com/2011/11/handler-and-activity-life-cycle-take.html

    Handler and Activity’s life cycle, take care about orphan threads!!

    Hello,

    You have an Activity which uses a Handler. You create your handler and overwrite the handleMessage method, you launch the handler’s thread and that’s it for the handler management… Most of us do such a thing and it’s a huge mistake!!! What happens to your thread when your activity pauses and resumes and worst when it dies and (re)creates?
    You thread becomes an orphan thread !
    So you have written something like that :

    (BAD CODE EXAMPLE DO NOT USE)

    /**

    * The handler

    */

    private final Handler slowDownDrawingHandler;

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

    // handler definition

    slowDownDrawingHandler = new Handler() {

    /** (non-Javadoc)*/

    @Override

    public void handleMessage(Message msg) {

    super.handleMessage(msg);

    redraw();

    }

    };

    // Launching the Thread to update draw

    Thread background = new Thread(new Runnable() {

    /**

    * The message exchanged between this thread and the handler

    */

    Message myMessage;

    // Overriden Run method

    public void run() {

    try {

    while (true) {

    // Sleep

    Thread.sleep(100);

    // Do something

    myMessage = slowDownDrawingHandler.obtainMessage();

    // then send the message

    slowDownDrawingHandler.sendMessage(myMessage);

    }

    }

    } catch (Throwable t) {

    // just end the background thread

    }

    }

    });

    // start the thread

    background.start();

    Using such a code, when your activity pauses or dies your thread is still alive and become an orphan thread. Nothing can stop it, neither inter-acts with it and it continues to run. This is a big fail.

    What is the right way to do it: You have to manage your thread state according to your activity state. In other words, when your activity pauses, you have to pauses your thread, when it resumes you have to resume your thread, when your activity dies, you thread must die….

    A simple way to do that is to use two atomic Booleans (synchronized boolean), isPausing and isStopping, change their value in the onResume, onPause, onCreate and onDestroy methods of your activity and use that boolean to pause or stop your thread.

    So the right code should look like that:
    Good Code Example CAN BE USED

    /** * The handler  */

    private final Handler slowDownDrawingHandler;

    /** * An atomic boolean to manage the external thread’s destruction */

    AtomicBoolean isRunning = new AtomicBoolean(false);

    /** * An atomic boolean to manage the external thread’s destruction */

    AtomicBoolean isPausing = new AtomicBoolean(false);

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

    // handler definition

    slowDownDrawingHandler = new Handler() {

    @Override

    public void handleMessage(Message msg) {

    super.handleMessage(msg);

    redraw();

    }

    };

    // Launching the Thread to update draw

    Thread background = new Thread(new Runnable() {

    /**

    * The message exchanged between this thread and the handler

    */

    Message myMessage;

    // Overriden Run method

    public void run() {

    try {

    while (isRunning.get()) {

    if(isPausing.get()) {

    Thread.sleep(2000);

    }else {

    // Sleep

    Thread.sleep(100);

    // Do something

    myMessage = slowDownDrawingHandler.obtainMessage();

    // then send the message

    slowDownDrawingHandler.sendMessage(myMessage);

    }

    }

    }

    } catch (Throwable t) {

    // just end the background thread

    }

    }

    });

    // Initialize the threadSafe booleans

    isRunning.set(true);

    isPausing.set(false);

    background.start();

    }

    /*(non-Javadoc) */

    @Override

    protected void onPause() {

    //and don’t forget to stop the thread

    isPausing.set(true);

    super.onPause();

    }

    /*(non-Javadoc) */

    @Override

    protected void onResume() {

    //and don’t forget to relaunch the thread

    isPausing.set(false);

    super.onResume();

    }

    /*(non-Javadoc) */

    @Override

    protected void onDestroy() {

    //and don’t forget to kill the thread

    isRunning.set(false);

    super.onDestroy();

    }
    So, Thanks who?
    Thanks, Android2ee, the Android Programming Ebooks :o)

    Mathias Séguy
    mathias.seguy.it@gmail.com
    Auteur Android2EE
    Ebooks to learn Android Programming.

    Retrouvez moi sur Google+
    Suivez moi sur Twitter
    Rejoignez mon réseau LinkedIn ou Viadeo