在我们的一个应用程序中,我们使用带有通知的后台服务(基本上是前台服务,但是您知道了,活动可以关闭,而服务仍然有效)。
在此服务上,我们使用3个单独的HandlerThreads
和Handlers
来管理各种操作,这些操作会有一定的延迟(例如250毫秒)。现在,如果屏幕关闭,则需要停止这些操作,如果屏幕重新打开,则需要恢复这些操作,由于这种情况,我们向该服务添加了一个广播接收器,并创建了删除的线程。到目前为止一切正常。
为了停止操作,我们通过调用Handler.removeCallbacksAndMessages(null)
删除了处理程序上的消息,并且实际上清除了消息队列。 但是,处理程序线程仍然存在。这是一个问题。
为了停止线程,我们使用了HandlerThread.quit()
,该线程内部调用了我们认为的Looper.quit()
,它将完成该线程,但是没有先生,它不会删除该线程,因为我们得到了一些报告来自pthread_create failed (1040kb stack), try again
之类的Fabric。在其下,有940个单独的线程命名相同,这导致了OOM(内存不足)错误。这对我们来说是一个巨大的错误。
问题:我们如何停止处理程序线程? HandlerThread.interrupt()
就足够了吗?任何帮助表示赞赏,谢谢。 PS:我无法共享任何源代码,在这种情况下,由于问题本身是不言而喻的,因此我认为这是没有必要的。
编辑:由于您要输入一些代码,因此,我在此展示一些我遵循的逻辑示例。
public class ThreadHelper implements Runnable
{
private HandlerThread handlerThread = new HandlerThread("ThreadName");
private Handler handler;
private boolean shouldRun = true;
public ThreadHelper()
{
handlerThread.start();
startThread();
}
// Called if the screen state is turned on.
public void startThread()
{
if (handlerThread == null)
{
handlerThread = new HandlerThread("ThreadName");
handlerThread.start();
}
if (handler == null)
{
handler = new Handler(handlerThread.getLooper());
handler.post(this);
}
}
// Called if the screen state is turned off.
public void stopThread()
{
shouldRun = false;
handler.removeCallbacksAndMessages(null);
handlerThread.quit();
try
{
handlerThread.interrupt();
}
catch (Exception ignored)
{
// Skipped Thread.currentThread().interrupt() check here since this is
// called from a different thread that is not associated.
}
// remove variables.
handler = null;
handlerThread = null;
}
@Override
public void run()
{
if (shouldRun)
{
// rest of the code without having a long-running
// operation. Mostly ends in 1~2 millseconds.
// Continue looping.
handler.postDelayed(this, 250);
}
}
}