Activity中Handler使用的正确姿势,避免内存泄漏

原博客地址:https://blog.csdn.net/weixin_40400031/article/details/96324854


 

使用Handler来解决通讯问题,是开发必备技能,但就是这家喻户晓的Handler,却偏偏最容易造成内存泄漏。

接下来我列出几种使用Handler的方式,以及各自的问题:

 

关于内存泄漏,请参考:Android 关于内存泄露,你必须了解的东西

关于JAVA引用类型,请参考:你真的懂 Java 的内存管理和引用类型吗?

 

第一种(公开静态handler):

写法:在Activiy中创建公开静态handler (public static Handler  handler),并在onCreate()中实例化,以给其他类使用。

优点:这样创建handler,可以随意实现Activity与Activity/Service进行通讯,只要在需要的地方,使用目的Activity的handler调用sendMessage()即可。

缺点:必会造成内存泄漏  (因为static变量本身不持有Activity的引用,但是在onCreate()中实例化就给handler加上了对Activity的强引用。当Activity销毁的时候,由于handler的强引用,导致Activity无法被GC回收)

解决办法:无药可救,被static变量持有了强引用,那就完了

 

第二种(非静态handler):

写法:在Activity创建一个非静态匿名内部类对象handler  (private Handler handler ) ,并在onCreate()中实例化

优点:相比于第一种,非静态handler不能被其他类随意使用,但依旧可以用于网络等耗时操作,用作结束时的通知(在调用耗时操作时将handler作为参数传递过去,之后等耗时操作结束,再使用该handler调用sendMessage()即可)。但是不会像第一种那样百分百造成内存泄漏。

缺点:1.只有Activity主动给予handler的地方才可以使用,无法实现Activity与Activity之间的通讯。

           2.如果Activity销毁时,Handler有未处理或处理中的Message,则Message持有handler,handler持有Activity,导致Activity无法回收

解决办法:在Activity的onDestroy()中调用handler.removeCallbacksAndMessages()切断Handler与Activity之间的引用。

 

第三种(自定义Handler,内部对Activity进行弱引用)

写法:

//创建子类,采用弱引用:
public abstract class MyHandler extends Handler  {
    private Activity activity ;
    private WeakReference<Activity> weakReference ;

    public MyHandler(Activity activity) {
        weakReference = new WeakReference<Activity>(activity);
    }

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

        if(weakReference.get() == null){
            return;
        }else{
            handle(msg); //处理message
        }
    }
    
    public abstract void handle(Message msg);
}
//在Activit中创建实例
public class HandlerActivity extends BaseActivity {
    public  MyHandler handler ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);

        handler = new MyHandler(context){
            @Override
            public void handle(Message msg) {
                //do something...
            }
        };
    }
}

优点:由于使用了弱引用(WeakReference),所以Activity销毁时,即使Handler还有message要处理,Activity也依旧会被GC回收。其他功能同第二种。

缺点:没啥缺点,就是要单独写个子类

 

最后:大家不要搞这么蛋疼的Handler了,在通讯这块还是使用EventBus这类成熟框架吧!

如果嫌EventBus书写分类繁琐,可以参考小弟的框架EventBox

 

以上若有不对的,还望指教,谢谢

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Service调用ActivityHandler对象可以通过以下步骤实现: 1. 在Activity定义Handler对象。 2. 在Service使用Messenger来与Activity通信。Messenger是一种轻量级的IPC方式,可用于不同进程间的通信。 3. 在Service创建一个Messenger对象,并将Activity定义的Handler对象传递给Messenger。 4. 在Activity通过bindService()方法绑定Service,并将Activity定义的Handler对象传递给Service。 5. 在Service使用Messenger向Activity发送消息,ActivityHandler对象将接收并处理消息。 下面是一个简单的示例代码: 在Activity定义Handler对象: ``` private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // 处理消息 } }; ``` 在Service创建Messenger对象,并将Activity定义的Handler对象传递给Messenger: ``` private Messenger mMessenger = new Messenger(new Handler() { @Override public void handleMessage(Message msg) { // 接收Activity发送的消息 } }); ``` 在Activity通过bindService()方法绑定Service,并将Activity定义的Handler对象传递给Service: ``` Intent intent = new Intent(this, MyService.class); intent.putExtra("handler", mHandler); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); ``` 在ServiceActivity发送消息: ``` Message msg = Message.obtain(); msg.what = 1; mMessenger.send(msg); ``` 在ActivityHandler对象将接收并处理消息: ``` @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: // 处理消息 break; default: super.handleMessage(msg); break; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值