Acyivity中使用Handler 以及警告的去除

一 背景:
我们经常会使用Handler这个消息处理类,然而你会发现,当你在activity内部new其对象的时候会有警告信息的。
二 警告信息的产生:
1 activity执行了 finish() 方法 ,但是被延迟处理还未处理的消息 包含对handler的引用。
2 此处handler为匿名内部类,匿名内部类持有外部类的强引用。
3 导致Activity无法回收,很多资源都无法回收,产生了内存泄露
三 解决方案

思路1:
静态内部类不对外部持有引用,所以定义成静态类的handler
加上个static警告就消失了
思路2:
要想彻底解决使用 弱引用(WeakReference)

官方建议
1内部类声明弱引用<引用外部类>对象
2内部类构造时创建”弱引用<引用外部类>”对象
3内部类的方法通过弱引用获取外部类对象,进行判断非空再操作

解决小demo

class OuterClass {

  class InnerClass {
    private final WeakReference mTarget;

    InnerClass(OuterClass target) {
           mTarget = new WeakReference(target);
    }

    void doSomething() {
           OuterClass target = mTarget.get();
           if (target != null) {
                target.do();    
           }
     }
}

四 运用到activity中:

局部代码:

 // 声明 静态handler
   static class MyHandler extends  Handler{
        //1弱引用<引用外部类>
       WeakReference mActivity;

        //2 构造创建弱引用
       public  MyHandler(Activity activity){
         mActivity = new WeakReference(activity);
      }
        @Override
        public void handleMessage(Message msg) {
            //通过弱引用获取外部类.
            Activity activity = mActivity.get();
            //进行非空再操作
            if (activity != null) {
              // 处理相关逻辑
                Toast.makeText(activity, "弱引用处理,收到消息", Toast.LENGTH_SHORT).show();
            }
        }
    }
  /* 弱引用的使用
    * */
    private void UseWeakReference() {
        // 在 新的线程中new handler 时 必须使用loop 类  故别再子线程中 new (原因 参考handler源码)
     final    MyHandler handler =   new MyHandler(MainActivity.this);
        // 首先开启线程
        new Thread(new Runnable() {
            @Override
            public void run() {


             // 通知 消息显示
             handler.sendEmptyMessage(0);
            }
        }).start();
    }

(运行结果 也就如代码一样弹出吐司,不在给出截图)

五 小结:

此篇文章知识难点还是较多的,如有不明白之处可以先参考java编程思想的内部类这一章,以及看看深入了解jvm这本书中java的四种引用介绍,以及有关handler源码的研究,也可以自己搜搜先关的文章看看。

你可能感兴趣的:(Acyivity中使用Handler 以及警告的去除)