小试牛刀-leakcannary

作者: 糖葫芦_倩倩 | 来源:发表于2018-10-23 16:56 被阅读12次

    leakcanary

    • build gradle配置
        debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.1'
        releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.1'
        // Optional, if you use support library fragments:
        debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.1'
    
    • 配置 application
    private RefWatcher refWatcher;
    
        public static RefWatcher getRefWatcher(Context context){
    
            HealthApplication application = (HealthApplication) context.getApplicationContext();
    
            return application.refWatcher;
        }
    
    • 监测
     RefWatcher refWatcher = MyApplication.getRefWatcher(this);//1
            refWatcher.watch(this);
    

    例如:我们写一个泄漏的代码

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout_event_bus);
    
            RefWatcher refWatcher = MyApplication.getRefWatcher(this);//1
            refWatcher.watch(this);
    
    
            Message message = Message.obtain();
            message.obj = "qianqian";
            message.what = 666;
            handler.sendMessageDelayed(message,600000);
        }
    
        Handler handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                Log.i("xx","handle message");
            }
        };
    
        public void sendMessage(View view){
            finish();
        }
    
    

    界面上一个按钮,点击按钮退出程序,在程序 onCreate 方法中我们发送了一个延时的消息,按照我们的分析,肯定会发生泄漏的。来我们看下leakcannary 给我们的提示:

    image.png

    我们知道当我们退出程序的时候 MessageQueue 中的消息还没执行完毕,MessageQueue.mMessages 这个变量持有的是Message 这个对象,而 Message.target中的 target持有的该Activityhandler引用,所以此时finish 掉的 activity 并不会被回收,导致LeakActivity 发生内存泄漏。

    • 其中一种解决办法呢,就是我们可以通过在点击或activity 退出时,removeMessage,例如:
    public void sendMessage(View view){
            handler.removeMessages(666);
            finish();
        }
    

    这样就不会有警告了。

    也可以通过静态内部类+弱引用的方式:

    private static class MyHandler extends Handler {
        private final WeakReference<LeakActivity> mActivity;
    
        public MyHandler(SampleActivity activity) {
          mActivity = new WeakReference<LeakActivity>(activity);
        }
    
        @Override
        public void handleMessage(Message msg) {
          LeakActivityactivity = mActivity.get();
          if (activity != null) {
            ...
          }
        }
      }
    private final MyHandler handler= new MyHandler(this);
    
     @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout_event_bus);
            Message message = Message.obtain();
            message.obj = "qianqian";
            message.what = 666;
            handler.sendMessageDelayed(message,600000);
        }
    }
    

    在实际项目中,可以用这个工具筛查一遍。

    相关文章

      网友评论

        本文标题:小试牛刀-leakcannary

        本文链接:https://www.haomeiwen.com/subject/nqpgzftx.html