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 !
You thread becomes an orphan thread !
/**
* 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
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
No comments:
Post a Comment