当我从中调用非静态方法时,如何使处理程序静态以避免泄漏?

Posted

技术标签:

【中文标题】当我从中调用非静态方法时,如何使处理程序静态以避免泄漏?【英文标题】:How to make handler static to avoid leak, when I call non static methods from it? 【发布时间】:2013-10-24 13:37:50 【问题描述】:

所以我有一项服务,它通过蓝牙与某些硬件进行通信。 Service 包含一个用于接收来自活动的消息的处理程序。此消息是服务操作的命令/指令。 Handler 简单定义为:

class IncomingHandler extends Handler 
        @Override
        public void handleMessage(Message msg) 

            switch (msg)
            case: blahblah ....
               break;
            case: blahblah ....
               break;
            
  

实际上一切正常,但 lint 警告我可能会发生泄漏,我应该将此处理程序设为静态...

这个 Handler 类应该是静态的,否则可能会发生泄漏。 问题:确保处理程序类不保留对外部的引用 class Id: HandlerLeak 在 android 中,Handler 类应该是静态的或者 可能会发生泄漏。在应用程序线程上排队的消息 MessageQueue 也保留自己的目标 Handler。如果处理程序是 内部类,它的外部类也将被保留。避免 泄漏外部类,将 Handler 声明为静态嵌套类 带有对其外部类的弱引用。

我的问题是我不能简单地将 Handler 设为静态,因为我正在调用非静态方法,具体取决于服务的消息。有些方法正在调用其他方法,而且它们有很多,所以我不可能将它们全部设为静态,不是吗?

在这里,我需要您更有经验的开发人员的建议。如何解决这个问题?谢谢

【问题讨论】:

向外部类添加弱引用 【参考方案1】:
Handler handler = new Handler(Looper.getMainLooper())...

您不需要创建 Java 类,只需创建一个处理程序并覆盖这些括号之间的 handleMessage 方法


    @Override
    public void handleMessage (Message msg)
    

【讨论】:

【参考方案2】:

我认为将处理程序设为静态是非常必要的。您可以声明一个“静态类 XXXHandler 扩展处理程序”,然后处理程序(消息的目标)不会保留对封闭类的引用。然后就不会泄露了。 如果你想在 Message 中传递一些东西,那么将它们放入 Message.object 中。如果有多个对象需要处理程序处理,只需将它们放在一个Object[]中,并在需要使用它们时使用强制转换。 我以前发现过这样的问题。 :)

【讨论】:

以上是关于当我从中调用非静态方法时,如何使处理程序静态以避免泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

当我无法将函数本身设为静态时如何调用非静态函数

如何使用 laravel 别名调用非静态方法

java中在一个类中定义的一个静态方法,怎么引用时可以直接用,不用对象.方法,也不用类.方法?

等效静态和非静态方法的速度差异很大

什么是静态方法?

如何从另一个类调用非静态抽象方法