引子
先来温习一下activity的生命周期
onCreate() >> onStart() >> onResume() >> onPause() >> onStop() >> onDestory()
清理资源的思路一般是在页面不在前台,即onPause() >> onStop() >> onDestory()几个方法中进行处理。通常做法是在onDestory()进行资源的释放,比如反注册、移除监听,变量置空等,比较简单的页面此逻辑不会有问题。
那有点复杂的呢?
页面添加了监听,退出的时候还没走到onDestory()此时收到了监听执行了相应的逻辑,清理资源已是不及时。
更加复杂
若activity页面是跳转而不是关闭
A:onPause() >> B:onCreate() >> B:onStart() >> B:onResume() >> A:onStop() ,此时虽然走了onPause()和onStop()方法,但页面并不是销毁。
继续复杂
若activity的启动模式是singleTask呢,此时不会走isFinishing(),页面跳转,在出入栈的时候已经调用了onPause()和onStop(),但因为栈中单例模式此时activity会直接走onDestory(),完美避开前面的资源清理。
几种处理方法
onDestory()清理资源
此方法试用于业务逻辑简单,无需及时释放资源的场景
@Override
protected void onDestroy() {
super.onDestroy();
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}
onStop()清理资源
此时activity已不可见,需要判断页面是否即将销毁则进行清理资源操作
@Override
protected void onStop() {
super.onStop();
if (isFinishing()){
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}
}
onPause()清理资源
此处清理资源的较少,activity处于不在前台但可能可见,建议放在onStop()方法处理
onFinish()清理资源
重写finish方法,在用户或系统调用finish时进行清理操作,早于onDestory()
@Override
public void finish() {
super.finish();
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}
小结
- onDestory() 方法释放资源适用于页面简单,无需考虑调用时间问题的场景
- onStop() 方法释放资源适用于,业务逻辑复杂,页面销毁需要立即清理资源的场景,但activity启动模式不是singleTask的场景
- onStop() + onDestory() 方法释放资源,将资源释放方法封装,在这两个生命周期调两次,适用于页面需要立即销毁并且activity启动模式是singleTask的场景
另外,还有两个思路,根据业务需求情况:
- 对于要释放的对象,做好逻辑,比如,保证其在释放过程中不可创建,或者在onCreate方法中去对这个对象做判断,可能的问题是,判断的逻辑会比较复杂。
- 如果APP调用层级较多,释放的资源可以进行异步操作,然后设置回调,当释放完成后进入回调,这个时候再去继续销毁Activity的操作
参考链接
- https://www.cnblogs.com/guanxinjing/p/11959000.html
- https://blog.csdn.net/Heijinbaitu/article/details/79153635
- https://zhuanlan.zhihu.com/p/433291690