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后的效果
2.打开后点返回键 3.打开Android Profiler 4.点击Memory区域 5.手动GC 6.手动GC后这里没有弄动态图,可能感觉不出来效果,建议直接导入项目运行查看。
手动GC的步骤:
1. 打开App
2. 点返回键关闭
3. 打开 Android Profiler Memory管理
4.手动点GC
5.查看Log 效果
看上图,这次已经没有了输出。说明弱应用确实有用。这下是不是可以放心的用协程了。开始浪吧。。。。
注意:验证过程中,一定要关闭Activity,否则GC无效。还有如果20秒不够GC,你可以把时间拉长一些。
总结
官方给出的两种方式解决协程的内存泄露问题,一种是统一协程上下文JobContext来解决,在activity 结束的时候调jobContext.cancle(), 但这种实现感觉耦合度高,不利于扩展维护。在这推荐大家使用这种方式解决。好了不聊了,去写标书了。。。。