纵使我们技术不是很全面但也阻挡不了我们想做好APP的心.
内存泄漏我们都只要要考虑,但是那么多我们总不能做到面面俱到,什么情况都可以考虑全面,还好前人种树后人乘凉,今天就简单介绍下Leakcancry 的继承.
准备工作
1.Gradle 引入
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.4'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'
2-1使用 Java 写法
public class IApplication extends Application {
public static RefWatcher getRefWatcher(Context context) {
IApplication application = (IApplication) context.getApplicationContext();
return application.mRefWatcher;
}
//用于自动监控调用Activity.onDestroy() 之后泄露的 activity。
RefWatcher mRefWatcher = null;
@Override
public void onCreate() {
super.onCreate();
//LeakCanary.install() 会返回一个预定义的 RefWatcher,同时也会启用一个 ActivityRefWatcher
mRefWatcher = LeakCanary.isInAnalyzerProcess(this) ? RefWatcher.DISABLED : LeakCanary.install(this);
}
Ps: 在BaseActivity 的onDestory 方法中 调用
IApplication.getRefWatcher(this).watch(this);
2-2 使用 Kotlin (正在练习,求师傅~~ )
class KApp : Application(){
private var refWatcher : RefWatcher ? = null
companion object {
private val TAG = "MyApplication"
var context: Context by Delegates.notNull()
private set
fun getRefWatcher(context: Context): RefWatcher? {
val kApp = context.applicationContext as KApp
return kApp.refWatcher
}
}
override fun onCreate() {
super.onCreate()
context = applicationContext
refWatcher = setupLeakCanary()
}
/**
* 初始化内存泄漏检测
*/
private fun setupLeakCanary(): RefWatcher {
return if (LeakCanary.isInAnalyzerProcess(this)) {
RefWatcher.DISABLED
} else LeakCanary.install(this)
}
}
PS:在BaseActivity 的onDestory 方法中 调用
KApp.getRefWatcher(this)?.watch(this)
工作机制 (摘自: rongbinjava的博客)
-
RefWatcher.watch()
创建一个 KeyedWeakReference 到要被监控的对象。 -
然后在后台线程检查引用是否被清除,如果没有,调用GC。
-
如果引用还是未被清除,把 heap 内存 dump 到 APP 对应的文件系统中的一个
.hprof
文件中。 -
在另外一个进程中的
HeapAnalyzerService
有一个HeapAnalyzer
使用HAHA 解析这个文件。 -
得益于唯一的 reference key,
HeapAnalyzer
找到KeyedWeakReference
,定位内存泄露。 -
HeapAnalyzer
计算 到 GC roots 的最短强引用路径,并确定是否是泄露。如果是的话,建立导致泄露的引用链。 -
引用链传递到 APP 进程中的
DisplayLeakService
, 并以通知的形式展示出来。
网友评论