handler内存泄漏

来源:互联网 发布:淘宝国际转运公司时效 编辑:程序博客网 时间:2024/04/30 00:01

起因

private final Handler mHandler = new Handler(){  ,....}

在Activity 中,Android lint可能会出现这样的一个warning: In Android,Handler classes should be static or leaks might occur.

意思是说: 在android中,handler应该是静态的,否则可能会发生内存泄漏

为什么会导致内存泄漏?

1、在java中,no-static的内部类会隐式持有当前类的一个引用,static则不会。

2、在android程序创建的时候,在主线程同时会创建一个Looper对象。Looper实现了一个简单的消息队列,一个接着一个处理message对象。主线程的looper存在于整个应用的生命周期中。

3、当一个handler在主线程中创建时,它会关联到looper的message queue。message添加到消息队列中的时候message会持有当前handler引用,当looper处理到当前消息的时候,会调用handler#handlermessage(message).

何种情况容易出现泄漏

我们知道非static的handler会持有activity的引用,而如果handler没有处理完成工作的时候,我们调用finish,则activity不能释放,这个时候就会出现内存泄漏。

解决方法

方法一:通过程序逻辑来进行保护。

1.在关闭Activity的时候停掉你的后台线程。线程停掉了,就相当于切断了Handler和外部连接的线,Activity自然会在合适的时候被回收。

2.如果你的Handler是被delay的Message持有了引用,那么使用相应的Handler的removeCallbacks()方法,把消息对象从消息队列移除就行了

方法二: static + 弱引用

#Activity SampleActivity.classprivate static class MyHandler extends Handler{  private final WeakReference<SampleActivity> mActivity;  public Handler(SampleActivity activity){    mActivity = new WeakReference<SampleActivity>(activity);  }  @override  public void handlerMessage(Message message){    SampleActivity activity = mActivity.get();    if(activity != null){        ....    }  }}
  • 这里为什么要使用弱引用?
    当我们使用static进行修饰之后,handler不能拿到activity的引用,因此我们也不能使用handler进行ui的操作了,所以需要使用若引用关联activity.

note : 当我们使用内部类的时候,应该使用静态修饰,以避免内部类持有外部类的引用

0 0