前言:近日在测试时,发现bug,聊天页面的数据,有时候有,有时候没有。经过查找,原来是这个页面销毁后,很长时间才回调OnDestroy()方法!如果在回调OnDestroy()方法之前,又重新点击这个页面,就导致这个页面没有数据。
导致原因:
在OnDestroy()中进行了数据存储等操作!
原因分析:
先附上源码中Activity的OnDestroy()的官方解释:
* Perform any final cleanup before an activity is destroyed. This can
* happen either because the activity is finishing (someone called
* {@link #finish} on it, or because the system is temporarily destroying
* this instance of the activity to save space. You can distinguish
* between these two scenarios with the {@link #isFinishing} method.
*
* <p><em>Note: do not count on this method being called as a place for
* saving data! For example, if an activity is editing data in a content
* provider, those edits should be committed in either {@link #onPause} or
* {@link #onSaveInstanceState}, not here.</em> This method is usually implemented to
* free resources like threads that are associated with an activity, so
* that a destroyed activity does not leave such things around while the
* rest of its application is still running. There are situations where
* the system will simply kill the activity's hosting process without
* calling this method (or any others) in it, so it should not be used to
* do things that are intended to remain around after the process goes
* away.
*
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
从官方文档中我们就可以找到解决办法了,就是在生命周期OnPause()执行时,判断当前的activity是否isFinishing(),如果isFinishing则可以提前进行一些数据操作等。
解决办法:
在OnPause()方法中通过判断当前的activity是否isFinishing提前就行数据操作,释放资源等操作。
如下:
@Override
protected void onPause() {
super.onPause();
if(this.isFinishing()) {
//进行数据操作及释放资源等操作
}
}
同时根据官方文档,如果要进行状态维护的话,最好在onSaveInstanceState方法中进行。
但是上面不能完美解决资源回收的问题。如果一个activity的启动模式为singleTask,先后被启动多次的话,前面几次执行onPause时不会执行回收资源的代码,故还需要在onDestroy()中进一步检测。
下面就直接引用博文Activity onDestroy() 回调缓慢问题分析及完美解决方案中的方案:
private boolean isDestroyed = false;
private void destroy() {
if (isDestroyed) {
return;
}
// 回收资源
isDestroyed = true;
}
@Override
protected void onPause() {
super.onPause();
if (isFinishing()) {
destroy();
}
}
@Override
public void onDestroy() {
destroy();//需要在onDestroy方法中进一步检测是否回收资源等。
}
参考博文:
Activity onDestroy() 回调缓慢问题分析及完美解决方案
Activity onDestroy() 调用研究