kotlin协程高级玩法之弱引用、解决协程导致的内存泄露

前言

协程如线程一样,使用不当就会导致Activity内存泄漏,在解决内存泄漏的方法中,弱引用是最常用的封装,大家都知道WeakHandler就是例子。

项目地址

封装

第一步

封装弱引用类WeakRef,声明WeakReference类常量,将弱引用的对象any传入该常量构造函数。提供invoke方法返回弱引用的实例。

WeakRef

第二步

为了方便调用,给任何类型的对象扩展函数weakReference函数

扩展

第三步

如何使用:稍微有点复杂,详细解释下

testWeakRef 函数
负责创建异步协程处理任务,最外层协程实在主线程中,首先创建一个异步协程         taskAsync负责倒计时日志输出,作用是在手动GC后看看是什么效果。
taskOrder负责延迟20秒后再往下执行showData()
weakRef()其实等于weakRef.invoke() 获取当前Activity实例

showData 函数
负责打印输出结果,最终看它是否在activity被GC掉后继续执行,来判断弱应用是否有效避免内存泄露。

验证

通过studio自带的Android Profiler 手动GC来验证下看看。

第一步:先来看看没有GC的效果图

在正常的Activity没有关闭的情况下,倒计时到20秒的时候打印出来。

第二步:手动GC后的效果

这里没有弄动态图,可能感觉不出来效果,建议直接导入项目运行查看。
手动GC的步骤:
1. 打开App 
2. 点返回键关闭
3. 打开 Android Profiler Memory管理 
4.手动点GC
5.查看Log 效果

2.打开后点返回键

3.打开Android Profiler

4.点击Memory区域

5.手动GC

6.手动GC后

看上图,这次已经没有了输出。说明弱应用确实有用。这下是不是可以放心的用协程了。开始浪吧。。。。
注意:验证过程中,一定要关闭Activity,否则GC无效。还有如果20秒不够GC,你可以把时间拉长一些。

总结

官方给出的两种方式解决协程的内存泄露问题,一种是统一协程上下文JobContext来解决,在activity 结束的时候调jobContext.cancle(), 但这种实现感觉耦合度高,不利于扩展维护。在这推荐大家使用这种方式解决。好了不聊了,去写标书了。。。。