6

handler在单独的线程中完成一项耗时的任务后,我正在使用一个对象继续 UI 工作。上面的 Lint 警告有问题,下面是我的方法。

[示例处理程序对象类型 1] ->

Handler responseHandler = new Handler()
{
    @Override
    public void handleMessage(Message msg)
    {
        super.handleMessage(msg);
        Toast.makeText(MainActivity.this, "Finished the long running task in seperate thread...", Toast.LENGTH_LONG).show();
    }       
};

[示例处理程序对象类型 2] ->

Handler responseHandler = new Handler(new Handler.Callback() 
{       
    @Override
    public boolean handleMessage(Message msg) 
    {   
        Toast.makeText(MainActivity.this, "Finished long running task in a seperate thread...", Toast.LENGTH_LONG).show();
        return false;      // RETURN VALUE ????
    }
});

在单独的线程(除了 UI)中,当耗时任务完成时,它执行以下行以将控制权返回给 UI 线程(基本上是处理程序 obj)。

responseHandler.sendEmptyMessage(0);

该程序适用于两种类型的处理程序对象,但对于第一种类型,我收到一个 Lint 警告,说This Handler 类应该是静态的,否则可能会发生泄漏

因此,我开始使用第二种类型的处理程序对象来避免 Lint 警告,但我遇到的问题是,我不确定第二种方式的返回值(真/假)的含义,它也适用于任何一种。我在谷歌上搜索了很多,但没有得到解释这个返回值的确切答案。

是的,我看到这个问题在stackoverflow的很多地方都问过,主要是重新整理Lint警告,但我的问题主要是关于第二种方式的返回类型,并确认它是否可以使用第二种方式解决问题处理程序 Obj。

问题->

1)。有谁知道这个返回值是什么意思(真/假)?

2)。这是我为摆脱棉绒警告所做的正确事情吗?

谢谢...

4

2 回答 2

5

每个处理程序都绑定到Looper一个线程,每个处理程序Message都放置在一个数据结构上,即一个消息队列。

Message有一个target指向 a的变量,Handler一个指向 a 的callback变量Runnable

因此,如果您使用匿名类来创建Handler对象(如第一个示例中所示),那么请知道匿名/非静态内部类包含对外部对象的引用(活动?)。因此,发布在队列上的消息可能持有对Handleras 目标的引用,而Handler反过来又持有对外部类的引用,例如Activity.

现在,只要线程正在运行,一条消息就可以在消息队列中停留很长时间。同时,该活动可能已被取消。但是由于消息具有的模糊间接引用,它不会被垃圾收集。请注意,只要线程正在运行,Looper 和消息队列就会一直存在。

在第二个示例中,您没有创建匿名Handler类。您正在使用处理程序构造函数并将其传递给匿名Callback对象。这可能会阻止 Lint 抱怨,但我怀疑这是一个好方法。只需避免内部类,避免将 Activity 或上下文引用传递给 Handler。

更新:

处理dispatchMessage()程序获取要处理的消息,检查是否提供了回调,如果提供了回调,则不调用handleMessage(),如果回调handleMessage()返回 true:

public void dispatchMessage(Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg); //--won't be called if you return true.
    }
}
于 2013-08-13T11:00:37.283 回答
1

我通过内部类(如处理程序)找到了一些有关内存泄漏的重要信息,并希望与您分享:

如何泄漏上下文:处理程序和内部类 我认为处理程序类的重写方法不会返回任何内容,您可以检查: handleMessage()

您已经覆盖了 Java Handler 类而不是 Android Handler,您可以看到 Java Handler 类的 handleMessage() 具有 return 语句,您还可以在此处检查 return 语句的原因:boolean handleMessage(C context)

于 2013-08-13T10:38:46.740 回答