我应该在销毁活动时手动关闭我的应用程序创建的HandlerThreads吗?

时间:2013-02-18 08:42:53

标签: android activity-lifecycle android-handler

我的应用由一个Activity组成。在这个活动中,我正在创建多个HandlerThread,它们在循环中运行以执行套接字阻塞操作。

目前,我在HandlerThread期间向这些Activity.onDestroy()的所有人发送了退出邮件。

有时,当我打开我的应用程序,关闭它并重新启动它时,它会崩溃(很多时候是因为向未运行的处理程序线程发送消息)。

我的问题是:关闭我的应用时关闭HandlerThread的正确方法是什么?(请注意,这些线程可能在套接字操作上被阻止)。

编辑:更多信息: 我有一个在onCreate中启动的Handler Threads池(当我第一次启动我的应用程序时没问题。)

每个处理程序的runnable循环都包含一个

 if (shouldRun) {
//body
} 
else { 
 close();
}

语句。

close方法删除所有待处理的消息和runnables,并向处理程序发送一条消息,使其调用looper.quit()。 这样,如果当前处理程序线程被IO操作阻止,只有一旦它完成它,他将退出()。

5 个答案:

答案 0 :(得分:3)

是的,关闭它是个好主意。还要确保删除回调。

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

答案 1 :(得分:1)

  • 你必须有一些不一致,否则你的应用程序不会崩溃。你确定 HandlerThread没有运行是真的吗?创建Activity时不要创建HandlerThread对象吗?
  • 如果您的HandlerThreads正在等待I / O操作,我会考虑尝试中断它们。简单地删除回调和消息并要求Looper退出,甚至向Handler发送temrination消息也不会做任何事情。 HandlerThread对象仍然存在,直到Android杀死进程(可能会或可能不会发生)。这意味着“您的应用将收集可能无法访问的僵尸HandlerThread对象”。当然,除非您可以向HandlerThreads发送一条终止消息,该消息会在他们阻止的频道上到达。
  • 重新使用HandlerThread对象会好得多。服务可能是正确的模型。
  • 此外,如果线程在您的活动中存活,您需要通知他们他们的通信对等体(您的活动)已经消失。否则,他们可能会提到已经消失的事情。

答案 2 :(得分:0)

最佳做法方法是删除活动onDestroy()中处理程序的回调。有关更多信息,请参阅此答案:

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

答案 3 :(得分:0)

当Looper退出时,HandlerThread停止。停止活动时,HandlerThread.getLooper()。quit()。 (有关使用HandlerThread的正确例子,请参阅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

答案 4 :(得分:0)

    /**
 * 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;
}

上面是HandlerThread.java源代码的'quit'方法,只是直接调用它。

为什么要叫退出?下面是HandlerThread.java源代码的'run'方法。

    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;
}

答案是'loop is a'while(true)'方法,它将返回,直到收到一个带有null target的Message。