我的应用程序是由一个单一的Activity 。 在这个活动中,我创build了多个在循环中运行的HandlerThread ,以执行套接字阻塞操作。
目前,我在Activity.onDestroy()期间向这些HandlerThread的每个人发布了一条退出消息。
有时,当我打开我的应用程序,closures它,并重新启动,它崩溃(很多时间,因为发布一个消息处理程序线程不运行)。
我的问题是: closures我的应用程序时closuresHandlerThread的正确方法是什么? (请注意,这些线程可能会阻塞套接字操作)。
编辑:更多信息:我有一个处理程序线程池,这是在onCreate(当我第一次启动我的应用程序时没有问题)启动。
每个处理程序的可运行循环都包含一个
if (shouldRun) { //body } else { close(); }
声明。
close方法移除所有待处理的消息和可运行参数,并向处理程序发送消息,使其调用其looper.quit() 。 这样,如果当前处理程序线程被IO操作阻塞,只有一次它将完成它将退出()。
你必须有一些不一致,否则你的应用程序不会崩溃。 你确定没有运行的HandlerThread真的是这个原因吗? 当你的Activity创build的时候你不创buildHandlerThread对象吗?
如果您的HandlerThreads正在等待I / O操作,我会考虑尝试并中断它们。 简单地删除callback和消息,并要求活套退出,即使发送temrination消息给处理程序,将无所作为。 HandlerThread对象将一直存在,直到Android终止进程(可能发生也可能不发生)。 这意味着“你的应用程序将收集可能无法访问的僵尸HandlerThread对象”。 当然,除非你能发送这些HandlerThreads一个终止信息到达他们阻塞的信道上。
重新使用HandlerThread对象会好得多。 一个服务可能是这样做的正确模式。
另外,如果线程在您的活动中存活,您需要通知他们他们的通信对方(您的活动)已经消失。 否则,他们可能会提到已经消失的东西。
是的,closures它是个好主意。 另外请确保删除您的callback。
@Override public void onDestroy() { super.onDestroy(); handler.removeCallbacksAndMessages(null); handler.getLooper().quit(); }
最佳实践方法是在您的活动onDestroy()删除callback给您的处理程序。 看到更多的答案:
/** * 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源代码的“退出”方法,直接调用即可。
为什么要叫退出? 下面是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; }
答案是'循环是一个'while(true)'方法,它将返回,直到收到一个带有空目标的消息。