Android Memory Leak: Multiple instances of activity in multiple threads
I need a "Loading" progressdialog to ap开发者_运维知识库pear at the start of an activity, and then display some stuff after loading is finished. In my onresume, I have code similar to this:
loadThread = true;
Thread showDetailsThread = new Thread() {
@Override
public void run() {
while (loadThread == true) {
Looper.prepare();
try {
dialog = ProgressDialog.show(myactivity.this, "", "Loading data...", true);
} finally {
handler.sendEmptyMessage(0);
}
Looper.loop();
}
}}; showDetailsThread.start();
The handler (not shown) displays everything I need displayed, and while the data is loading, the progressdialog displays as expected. The problem is, after running the memory analyzer in eclipse, I realized that every time I visit this activity it spawns a new instance of everything created by the handler in a new thread, without destroying the previous one. With multiple instances of the activity running forever in multiple threads, I eventually run out of memory.
Here's what I don't understand. I was under the impression that, given the above example, the handler would run in the main ui thread, not in the new thread containing the dialog. The only thing that should exist in the new thread is the progressdialog, and the dialog is instantly dismissed at the beginning of the handler (not shown), which should stop the thread, right? Why are these threads being created and running indefinitely? BTW, I have "loadThread = false;" in my onpause, ondestroy, and onstop in an attempt to halt the thread after navigating to another activity, but it doesn't work.
If I just call the handler directly instead of running it in the showdetailsThread finally{}, everything is fine and there is no leak, but I really need the progressdialog to appear during the 2 second delay that occurs during loading.
There is probably a better way to do this anyway. Any help is greatly appreciated.
No more memory leak now. I needed to create a handler within the new thread, which would bind to the Looper (somewhere between Looper.prepare() and Looper.loop():
threadKillerHandler = new Handler();
And then call quit() on the looper's handler when I'm done with the thread (in onDestroy in my case):
threadKillerHandler.getLooper().quit();
Otherwise the thread will run forever, and instances will keep piling up every time a user revisits the activity.
I would suggest using AsynchTask
instead of the way you are doing it. This will precent the multiple instances appearing.
- Documentation
- Example
精彩评论