本文介绍了Android:将消息发布到HandlerThread会使UI线程无响应或给出IllegalStateException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在android中使用HandlerThread,并最终遇到UI线程不再响应的情况,或者出现奇怪的IllegalStateException.我想给你一个我的问题的最小例子.

I am trying to make use of HandlerThread in android and am ending up with either a situation in which the UI thread is not responding anymore, or a strange IllegalStateException. I want to give you a minimal example of my problem.

我有一个类DataManager,该类在创建时实例化了工作线程:

I have a class DataManager which instantiates a worker thread on creation:

public class DataManager
{
    private final HandlerThread loaderThread = new HandlerThread( "Worker" );
    private final Producer loader;

在此类中,我定义了Handler:

    private static class Producer extends Handler
    {
        public Producer( Looper looper )
        {
            super( looper );
        }

        @Override
        public void handleMessage( Message msg )
        {
            msg.recycle();
        }
    }

我的DataManager的构造函数运行工作线程,并将处理程序与线程的循环程序相关联:

The constructor of my DataManager runs the worker thread and associates the handler with the thread's looper:

    public DataManager()
    {
        loaderThread.start();
        this.loader = new Producer( loaderThread.getLooper() );
    }

在销毁DataManager之前,它将停止线程并等待其完成.实际上,我相信这部分与我的问题无关,因为我的DataManager实例肯定一直都在运行:

Before DataManager is destroyed, it stops the thread and waits for it to finish. Actually I believe this part is not relevant to my problem, because my DataManager instance is definitely alive all the time:

    @Override
    protected void finalize() throws Throwable
    {
        loaderThread.quit();
        loaderThread.join();

        super.finalize();
    }

最后,我有doSomething方法,该方法只是将消息发布到工作线程:

Finally, I have doSomething method, which simply posts a message to the worker thread:

    public void doSomething()
    {
        Message msg = Message.obtain();
        loader.sendMessage( msg );
    }

现在,我要从UI线程上的自定义视图内部实例化DataManager.当视图要使用onDraw绘制自身时,它将在DataManager上调用doSomething.进一步的行为取决于AsyncTask当前是否在后台运行:

Now I'm instantiating the DataManager from inside of a custom view on the UI thread. When the view is about to paint itself using onDraw it calls doSomething on the DataManager. The further behavior depends on whether an AsyncTask is currently running in background or not:

  • 如果它正在运行,则此刻UI线程将变得无响应.
  • 否则,我得到一个IllegalStateException,它从UI线程的Looper.loop子例程中抛出,说:

    • If it is running, than the UI thread is becoming unresponsive form this moment on.
    • Otherwise, I get an IllegalStateException, thrown from within a subroutine of Looper.loop of the UI thread, saying:

      推荐答案

      知道了.令人讨厌的是,有关回收邮件的情况是:

      Got it. Obsiously the situation about recycling messages is this:

      因此,一定不得在handleMessage中回收邮件.

      So one must not recycle the message within handleMessage.

      这篇关于Android:将消息发布到HandlerThread会使UI线程无响应或给出IllegalStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 04:32