2. 从架构设计角度分析AAC源码-我的LiveData

前言

本章重点是日常开发避免内存溢出,以及对该开发方式实现的迭代。

参考文献Android 内存泄漏检测工具 LeakCanary 的使用

参考文献Timber: Android日志记录

工具

Timber

其实是一个Log日志工具类,这里方便log统一管理。

gradle配置:

repositories {
  mavenCentral()
}

dependencies {
  implementation 'com.jakewharton.timber:timber:5.0.1'
}

在自定义的application oncreate方法中

@Override
public void onCreate() {
    super.onCreate();
    if (BuildConfig.DEBUG) {
        Timber.plant(new Timber.DebugTree());
    }
}

具体使用和Log一致!e.g.

Timber.e("error world!");

LeakCanary

LeakCanary 原理

LeakCanary 是通过在 Application 的 registerActivityLifecycleCallbacks 方法实现对 Activity 销毁监听的,该方法主要用来统一管理所有 Activity 的生命周期。所有 Activity 在销毁时在其 OnDestory 方法中都会回调 ActivityLifecycleCallbacks 的 onActivityDestroyed 方法,而 LeakCanary 要做的就是在该方法中调用 RefWatcher.watch 方法实现对 Activity 进行内存泄漏监控。
那么,LeakCanary 是如何判断某个 Activity 可能会发生内存泄漏呢?答案是:WeakReference 和 ReferenceQueue,即 LeakCanary 利用了 Java 的 WeakReference 和 ReferenceQueue,通过将 Activity 包装到 WeakReference 中,被 WeakReference 包装过的 Activity 对象如果能够被回收,则说明引用可达,垃圾回收器就会将该 WeakReference 引用存放到 ReferenceQueue 中。假如我们要监视某个 Activity 对象,LeakCanary 就会去 ReferenceQueue 找这个对象的引用,如果找到了,说明该对象是引用可达的,能被 GC 回收,如果没有找到,说明该对象有可能发生了内存泄漏。最后,LeakCanary 会将 Java 堆转储到一个 .hprof 文件中,再使用 Shark(堆分析工具)析 .hprof 文件并定位堆转储中“滞留”的对象,并对每个"滞留"的对象找出 GC roots 的最短强引用路径,并确定是否是泄露,如果泄漏,建立导致泄露的引用链。最后,再将分析完毕的结果以通知的形式展现出来。

使用

LeakCanary2.0 之前我们接入的时候需要在 Application.onCreate 方法中显式调用 LeakCanary.install(this); 开启 LeakCanary 的内存监控。

LeakCanary2.0 开始通过库里注册的 ContentProvier 自己开启 LeakCanary 的内存监控,无需用户手动再添加初始化代码。

gradle添加依赖

dependencies {
   
    // Leak Canary
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'

}

日常开发避免内存溢出

android中的数据应该是随着声明周期的变化而变化。例如一个Activity全局定义一个data数据:private Data data;,那么当前数据在oncreate方法中赋值:data = new Data();,在ondestroy销毁方法中销毁,并且销毁前也需要对data对象中的数据进行清除并且销毁:

public class MyActivity extends Activity{

	private Data data;

	@Override
	protected void oncreate(){
		data = new Data();
		//UI更新
		...
	}

	@Override
	protected void onDestroy() {
	  data.clear();
	  data = null;
	  super.onDestroy();
	}
}

public class Data{

	private Item item;
	private Map maps = new HashMap();
	...

	public void clear(){
		item.clear;
		maps.removeall();
		maps = null;
		item = null;
	}

}

以上(手敲)当然还有在onStart、onStop等待生命周期也可以做响应的操作,这样做是防止内存泄漏非常完美的方式:数据随着当前组件声明周期的变化而变化,手动进行清理并且置为null。

每个Activity都应该按照这种规则去实现,规则:Activity中定义全局变量Data,oncreate对Data赋值并且更新到UI,ondestroy销毁Data

迭代

完美的代码不是一次性完成的,而是根据实际需求不断迭代,最终形成符合当前业务逻辑的代码。

根据当前业务逻辑去设计合理的架构,当当前架构不满足实际需求时,在对新需求提出一个更加合理的设计思路。这就是为什么说思路比实现更重要,设计比代码更巧妙。

迭代一

我们是否可进一步迭代,如何迭代(方法千千万,选择一种即可,不纠结):
每个Activity中都会有data数据(即使有多个data,我们也可以封装成给data),data赋

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值