美文网首页
LeakCannary 原理分析

LeakCannary 原理分析

作者: 糖葫芦_倩倩 | 来源:发表于2018-11-06 15:54 被阅读28次

    上篇写到 leakcanary 的使用,这篇主要是了解LeakCannary 大概是如何工作的。

    1.首先它是如何监听Activity 销毁的?

    因为我们知道只有当activity 销毁(onDestroy())的时候,我们才能对这个activity 进行分析查看哪些对象可能存在内存泄漏。

    发现了如下代码:

    public static RefWatcher install(Application application) {
        return refWatcher(application).listenerServiceClass(DisplayLeakService.class)
            .excludedRefs(AndroidExcludedRefs.createAppDefaults().build())
            .buildAndInstall();
      }
    

    buildAndInstall() 中:

     public RefWatcher buildAndInstall() {
           ....
        if (refWatcher != DISABLED) {
          if (watchActivities) {
          //这是观察activity的
            ActivityRefWatcher.install(context, refWatcher);
          }
          if (watchFragments) {
            FragmentRefWatcher.Helper.install(context, refWatcher);
          }
        }
        LeakCanaryInternals.installedRefWatcher = refWatcher;
        return refWatcher;
      }
    
    public final class ActivityRefWatcher {
       ....
      public static void install(Context context, RefWatcher refWatcher) {
        Application application = (Application) context.getApplicationContext();
        ActivityRefWatcher activityRefWatcher = new ActivityRefWatcher(application, refWatcher);
        //拿到application,注册activity的生命周期回调
        application.registerActivityLifecycleCallbacks(activityRefWatcher.lifecycleCallbacks);
      }
    

    其中这个:lifecycleCallbacks 就是回调监听

    private final Application.ActivityLifecycleCallbacks lifecycleCallbacks =
          new ActivityLifecycleCallbacksAdapter() {//监听activity销毁
            @Override public void onActivityDestroyed(Activity activity) {
              refWatcher.watch(activity);
            }
          };
    

    那么我们也可以通过application 注册获取activity 的生命周期监听回调,如下是我写的:

    public class LifeCircleActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.life_layout);
    
            final Application application = (Application) getApplicationContext();
            application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                    Log.i("xx","activity is onActivityCreated...");
                }
    
                @Override
                public void onActivityStarted(Activity activity) {
                    Log.i("xx","activity is onActivityStarted...");
                }
    
                @Override
                public void onActivityResumed(Activity activity) {
                    Log.i("xx","activity is onActivityResumed...");
                }
    
                @Override
                public void onActivityPaused(Activity activity) {
                    Log.i("xx","activity is onActivityPaused...");
                }
    
                @Override
                public void onActivityStopped(Activity activity) {
                    Log.i("xx","activity is onActivityStopped...");
                }
    
                @Override
                public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
                    Log.i("xx","activity is onActivitySaveInstanceState...");
                }
    
                @Override
                public void onActivityDestroyed(Activity activity) {
    
                    application.unregisterActivityLifecycleCallbacks(this);
                    Log.i("xx","activity is onDestroy...");
                }
            });
    }
    

    这样我们就可以监听我们当前这个类的生命周期了,可以运行打印日志就知道了。

    2.内存泄漏的对象的引用路径

    这块使用到了 square 的另一个开源库 haha ,获取当前内存中的heap堆信息的snapshot

    相关文章

      网友评论

          本文标题:LeakCannary 原理分析

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