11

我的应用程序由单个Activity. 在这个活动中,我创建了多个HandlerThread在循环中运行以执行套接字阻塞操作的 s。

目前,我HandlerThreadActivity.onDestroy().

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

我的问题是:当我关闭我的应用程序时,正确的关闭方式是什么?HandlerThread(请注意,这些线程可能会阻塞套接字操作)。

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

每个处理程序可运行循环都用一个

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

陈述。

close 方法删除所有挂起的消息和可运行项,并向处理程序发布一条消息,这将导致他调用它的looper.quit(). 这样,如果当前的处理程序线程被 IO 操作阻塞,只有当它完成它才会退出()。

4

5 回答 5

3

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

@Override
public void onDestroy() {
    super.onDestroy();
    handler.removeCallbacksAndMessages(null);
    handler.getLooper().quit();
}
于 2013-02-18T08:46:39.123 回答
1
  • 你必须有一些不一致的地方,否则你的应用程序不会崩溃。您确定没有运行的 HandlerThread真的是原因吗?创建 Activity 时不创建 HandlerThread 对象吗?
  • 如果您的 HandlerThreads 正在等待 I/O 操作,我会考虑尝试中断它们。简单地删除回调和消息并要求 Looper 退出,甚至向 Handler 发送终止消息,都不会做任何事情。HandlerThread 对象仍然存在,直到 Android 终止进程(可能会发生也可能不会发生)。这意味着“您的应用程序将收集可能无法访问的僵尸 HandlerThread 对象”。当然,除非您可以向这些 HandlerThreads 发送终止消息,该消息到达它们阻塞的通道。
  • 重用 HandlerThread 对象会好得多。服务可能是执行此操作的正确模型。
  • 此外,如果线程在您的 Activity 中存活,您需要通知他们他们的通信对等方(您的 Activity)已经消失。否则,它们可能指的是已经消失的东西。
于 2013-02-18T09:01:25.763 回答
1
    /**
 * 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;
}

答案是'循环是一个'while(true)'方法,它会返回,直到收到一个目标为空的消息。

于 2015-02-02T16:11:00.190 回答
0

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

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

于 2013-02-18T08:50:42.480 回答
0

Looper 退出时 HandlerThread 停止。HandlerThread.getLooper().quit() 当你停止你的活动时。(见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是正确使用 HandlerThread 的一个很好的例子)

于 2013-02-18T09:01:24.010 回答