Android线程:此Handler类应该是静态的,否则可能会发生泄漏

Jib*_*ibW 6 java android android-handler

handler在一个单独的线程中完成一个耗时的任务后,使用一个对象来继续UI工作.有上述Lint警告的问题和跟随是我的方法.

[Sample Handler对象类型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();
    }       
};
Run Code Online (Sandbox Code Playgroud)

[Sample Handler对象类型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 ????
    }
});
Run Code Online (Sandbox Code Playgroud)

在完成耗时任务的单独线程(除了UI)之外,它执行以下行以将控件返回到UI线程(基本上是处理程序obj).

responseHandler.sendEmptyMessage(0);
Run Code Online (Sandbox Code Playgroud)

该程序对两种类型的处理程序对象都可以正常工作,但是对于第一种类型,我得到一个Lint警告说这个Handler类应该是静态的,否则可能会发生泄漏.

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

是的,我看到这个问题已经在stackoverflow中的许多地方被要求主要重写Lint警告,但我的问题主要是关于第二种方式的返回类型并且确认它是否正常我使用第二种类型解决问题的方式处理程序Obj.

问题 - >

1).有人知道这个返回值意味着什么(真/假)?

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

谢谢...

S.D*_*.D. 5

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

Message有一个target指向a Handlercallback变量,一个指向a 的变量Runnable.

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

现在,只要线程正在运行,消息就可以在消息队列中保留很长的时间间隔.同时,该活动可能已经被驳回.但它不会被垃圾收集,因为消息具有模糊的间接引用.请注意,只要线程正在运行,Looper和Message Queue就会保持不变.

在第二个示例中,您不是在创建匿名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.
    }
}
Run Code Online (Sandbox Code Playgroud)


Har*_*ara 1

我发现了一些关于内部类(如处理程序)内存泄漏的重要信息,并想与您分享:

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

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