@JvmOverloadsfunmanualInstall(application:Application,retainedDelayMillis:Long=TimeUnit.SECONDS.toMillis(5),watchersToInstall:List<InstallableWatcher>=appDefaultWatchers(application)){//检查是否是主线程checkMainThread()//如果已经安装过抛出异常if(isInstalled){throwIllegalStateException("AppWatcher already installed, see exception cause for prior install call",installCause)}check(retainedDelayMillis>=0){"retainedDelayMillis $retainedDelayMillis must be at least 0 ms"}installCause=RuntimeException("manualInstall() first called here")this.retainedDelayMillis=retainedDelayMillisif(application.isDebuggableBuild){LogcatSharkLog.install()}// Requires AppWatcher.objectWatcher to be set//获取LeakCanaryDelegate.loadLeakCanary(application)//遍历并调用install方法watchersToInstall.forEach{it.install()}}
overridefuninvoke(application:Application){_application=applicationcheckRunningInDebuggableBuild()//添加listenerAppWatcher.objectWatcher.addOnObjectRetainedListener(this)//创建AndroidHeapDumpervalheapDumper=AndroidHeapDumper(application,createLeakDirectoryProvider(application))//获取GcTiggervalgcTrigger=GcTrigger.DefaultvalconfigProvider={LeakCanary.config}valhandlerThread=HandlerThread(LEAK_CANARY_THREAD_NAME)handlerThread.start()valbackgroundHandler=Handler(handlerThread.looper)//创建HeapDumpTriggerheapDumpTrigger=HeapDumpTrigger(application,backgroundHandler,AppWatcher.objectWatcher,gcTrigger,heapDumper,configProvider)//application注册可见监听器application.registerVisibilityListener{applicationVisible->this.applicationVisible=applicationVisibleheapDumpTrigger.onApplicationVisibilityChanged(applicationVisible)}registerResumedActivityListener(application)addDynamicShortcut(application)// We post so that the log happens after Application.onCreate()mainHandler.post{// https://github.com/square/leakcanary/issues/1981// We post to a background handler because HeapDumpControl.iCanHasHeap() checks a shared pref// which blocks until loaded and that creates a StrictMode violation.backgroundHandler.post{SharkLog.d{when(valiCanHasHeap=HeapDumpControl.iCanHasHeap()){isYup->application.getString(R.string.leak_canary_heap_dump_enabled_text)isNope->application.getString(R.string.leak_canary_heap_dump_disabled_text,iCanHasHeap.reason())}}}}}
privatevalapplication:Application,privatevalreachabilityWatcher:ReachabilityWatcher):InstallableWatcher{privatevallifecycleCallbacks=object:Application.ActivityLifecycleCallbacksbynoOpDelegate(){overridefunonActivityDestroyed(activity:Activity){//Activity执行onDestory时调用expectWeaklyReachablereachabilityWatcher.expectWeaklyReachable(activity,"${activity::class.java.name} received Activity#onDestroy() callback")}}overridefuninstall(){//为application注册Activity生命周期回调application.registerActivityLifecycleCallbacks(lifecycleCallbacks)}overridefununinstall(){application.unregisterActivityLifecycleCallbacks(lifecycleCallbacks)}}
overridefunonActivityStopped(activity:Activity){// This could happen if the callbacks were registered after some activities were already// started. In that case we effectively considers those past activities as not visible.if(startedActivityCount>0){startedActivityCount--}if(hasVisibleActivities&&startedActivityCount==0&&!activity.isChangingConfigurations){//设置为不可见hasVisibleActivities=falseupdateVisible()}}
funonApplicationVisibilityChanged(applicationVisible:Boolean){if(applicationVisible){applicationInvisibleAt=-1L}else{//不可见applicationInvisibleAt=SystemClock.uptimeMillis()// Scheduling for after watchDuration so that any destroyed activity has time to become// watch and be part of this analysis.scheduleRetainedObjectCheck(delayMillis=AppWatcher.config.watchDurationMillis//延迟时间,配置是5s)}}