Should I manually close HandlerThreads created by my application when destroying the activity?

落爺英雄遲暮 提交于 2019-12-05 02:45:26
class stacker
  • You must have some inconsistency there, otherwise your App wouldn't crash. Are you sure that a HandlerThread which is not running is really the reason? Don't you create HandlerThread objects when your Activity is created?
  • If your HandlerThreads are waiting on I/O operations, I would consider to try and interrupt them. Simply removing callbacks and messages and asking the Looper to quit, even sending temrination messages to the Handler, will do nothing. The HandlerThread object will still be around until Android kills the process (which may or may not occur). This means that "your app will collect zombie HandlerThread objects" which are probably unreachable. Unless, of course, you can send those HandlerThreads a termination message which arrives on the channel they block on.
  • It would be much better to re-use the HandlerThread objects. A Service might be the right model to do this.
  • Also, if Threads survive your Activity, you need to inform them that their communication peer (your Activity) is gone. Otherwise, they may refer to something which is already gone.

Yes, it would be a good idea to close it. Also make sure to remove your callbacks.

@Override
public void onDestroy() {
    super.onDestroy();
    handler.removeCallbacksAndMessages(null);
    handler.getLooper().quit();
}
Anup Cowkur

The best practices approach would be to remove the callbacks to your handlers in your activities onDestroy(). See this answer for more:

https://stackoverflow.com/a/5038542/1369222

The HandlerThread is stopped when the Looper is quitted. HandlerThread.getLooper().quit() when you stop your activity. (see http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/app/IntentService.java#IntentService.ServiceHandler.%3Cinit%3E%28android.os.Looper%29 for a good example of a proper HandlerThread use)

    /**
 * Ask the currently running looper to quit.  If the thread has not
 * been started or has finished (that is if {@link #getLooper} returns
 * null), then false is returned.  Otherwise the looper is asked to
 * quit and true is returned.
 */
public boolean quit() {
    Looper looper = getLooper();
    if (looper != null) {
        looper.quit();
        return true;
    }
    return false;
}

Above is the 'quit' method of the source code of HandlerThread.java, just invoke it directly.

Why should called quit? Below is 'run' method of the source code of HandlerThread.java.

    public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();//always loop except for a Message with null target

    mTid = -1;
}

The answer is 'loop is a 'while(true)' method,It will return until receive a Message with null target.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!