我是苍王,如下是我这个系列的相关文章,有兴趣能够参考一下,能够给个喜欢或者关注个人文章。 [Android]如何作一个崩溃率少于千分之三噶应用app--章节列表bash
近来遇到一个比较奇怪的Fragment问题 app不少时候会使用Viewpager+Fragments的方式显示布局,特别是在主页。 若是app在栈内已经打开了几个Activity了,忽然之间发生崩溃,通常状况下崩溃被捕抓后,会从新恢复试着从新恢复栈顶的崩溃前的Activity。 对于这种崩溃状况,Activity毫无疑问崩溃前会走onSaveInstanceState函数,恢复时会走onRestoreInstanceState恢复场景。 可是当包含ViewPager+Fragments的Activity被触发恢复后,你会发现居然这些Fragments会有内存泄漏的状况。 分析: 这个很是不容易发现,使用Profile查看app对象的时候,会发现这些Fragments会被建立了两次,这种状况是没法经过LeakCanary来侦查到的,由于是主的Activity作出的泄漏。 并且顶上显示的Fragment并非Activity所持有的Fragments,若是是某些数据是从Activity中获取的,将会没法显示。 缘由: 翻阅了源码,咱们能够看到如下的FragmentActivity恢复的代码和重建FragmentActivity的onCreate流程架构
/**
* Save all appropriate fragment state.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//记录哪些Fragments被建立了
markFragmentsCreated();
//保存Fragments状态
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
……
}
@SuppressWarnings("deprecation")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
mFragments.attachHost(null /*parent*/);
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
//栈中的Fragments恢复状态
mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
……
}
mFragments.dispatchCreate();
}
复制代码
这里能够看到奔溃的时候mFragments的会在onSaveInstanceState被记录已经建立了,而且会被调用了saveAllState,而后重建时onCreate会调用restoreAllState,恢复Fragment,而后从新建立一次Fragments,通常状况下super.onCreate会在子类调用以前执行,这个时候Fragments的恢复会比子类Activity onCreate要前。 而后从新走onCreate流程,而后从新建立ViewPager和Fragments。那么Fragments就会被建立两次了。 解决方法: 没法知道在恢复的mFragments的TAG标志,因此Activity没法经过TAG获取。app
1.在onSaveInstanceState的时候,不调用super的方法,直接调用FragmentActivity.onStateNotSaved(),直接截断mFragments会恢复栈。但这样onSaveInstanceState就会没法恢复状态,有可能有未知的错误,因此不采纳 2.在onCreate的流程的时候,先判断supportFragmentManager.fragments是否有对应的Fragment,而后若是存在就不建立屡次,直接在supportFragmentManager.fragments中获取。ide
失败方案,对supportFragmentManager.fragments清空是无效的,supportFragmentManager.fragments是不等价于FragmentActivity.mFragments的函数
这里还要谨记两点, 1.onRestoreInstanceState生命周期,是在onCreate以后,在onResume以前的,一些经过恢复的操做,只能在onResume中进行。 2.Application.LifeRecyleCallback没法监听到onRestoreInstanceState的执行。 组件化