Android Threading:这个 Handler 类应该是静态的,否则可能会发生泄漏[重复]

Posted

技术标签:

【中文标题】Android Threading:这个 Handler 类应该是静态的,否则可能会发生泄漏[重复]【英文标题】:Android Threading: This Handler class should be static or leaks might occur [duplicate] 【发布时间】:2013-08-14 21:59:08 【问题描述】:

在一个单独的线程中完成一项耗时的任务后,我正在使用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 警告,说 这个处理程序类应该是静态的,否则可能会发生泄漏

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

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

问题 ->

1). 有谁知道这个 return 值的确切含义(真/假)?

2). 消除 lint 警告是正确的做法吗?

谢谢...

【问题讨论】:

是的,请查看链接的帖子。 我看到了这些链接,我的问题主要是关于我在这些链接中没有找到解释的返回值。 ***.com/questions/17899328/…。检查这个和这个groups.google.com/forum/#!topic/android-developers/1aPZXZG6kWk。查看 romain guy 对主题和解决方案的讨论。 【参考方案1】:

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

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

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

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

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

更新:

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.
    

【讨论】:

【参考方案2】:

我通过内部类(如 handler)发现了一些有关内存泄漏的重要信息,并希望与您分享:

How to Leak a Context: Handlers & Inner Classes 而且我认为 Handler 类的重写方法不会返回任何内容,您可以检查: handleMessage()

你已经覆盖了 Java Handler 类而不是 Android Handler,你可以看到 Java Handler 类的 handleMessage() 有 return 语句,你也可以在这里检查 return 语句的原因:boolean handleMessage(C context)

【讨论】:

以上是关于Android Threading:这个 Handler 类应该是静态的,否则可能会发生泄漏[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Card Hand Sorting 二进制枚举暴力

手眼标定eye-to-hand 示例:handeye_stationarycam_calibration

求高手老师指正 这个程序总是报错!no operator defined which takes a right-hand operand of type ''

Android之EventBus使用详解

手眼标定之相机随动eye-in-hand 示例:handeye_movingcam_calibration

Invalid left-hand side in assignment