項目中有一個activity頁面使用ViewPager,架曹,添加了兩個Fragment,我使用的ViewPager的adapter是繼承自FragmentPagerAdapter德挣,由于項目久遠這里顯示過時了,但也不影響使用。
遇到的問題是唤蔗,如果程序由于內存緊張在被系統(tǒng)回收后,此時再打開程序窟赏,程序會恢復到最后打開的頁面妓柜,我這里就是包含兩個fragment的頁面,當然打開后UI是顯示正常饰序,當fragment內使用requireActivity()方法時领虹,程序就出現異常,Fragment MyFragment not attached to Activity 求豫。塌衰。诉稍。,意思差不多就是fragment沒有附加到activtiy最疆,
我的activity中是在onCreate 中創(chuàng)建fragment杯巨,然后再設置ViewPager的adapter,最開始是程序被回收后再次恢復頁面任然在onCreate 方法中再次新建fragment努酸,然后再設置到ViewPager服爷,然而這樣做會導致ViewPager內重復添加fragment,FragmentPagerAdapter的工作原理:會在Activity重建時自動恢復Fragment的狀態(tài)获诈。這是通過Fragment的狀態(tài)保存機制實現的仍源。
再往上找了各種相關問題,基本都是說在Fragment中只是用isAdded()判斷是否附加到了activtity上了舔涎,然后再獲取requireActivity()笼踩,然而這樣并沒有根本解決問題,而且有些功能也會異常亡嫌。
最后經過幾經思索嚎于,查閱各種資料得出了解決之道:
程序回收后activity會執(zhí)行onSaveInstanceState 方法,用于保存一些數據以便在程序恢復時再次使用挟冠,這里就是在onSaveInstanceState 方法中保存fragment實例于购,然后在程序恢復時再獲取之前儲存的fragment,不需要創(chuàng)建新的fragment
第一步:
//當程序被回收時(旋轉屏幕等一些操作也會執(zhí)行)會執(zhí)行此方法知染,在這里使用getSupportFragmentManager()保存你的fragment
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, MyFragment.class.getName(), myFragment);
}
第二步:
//程序恢復后再在onCreate中肋僧,使用getSupportFragmentManager,獲取儲存的fragment
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) { //這里判斷一下是否是恢復狀態(tài)持舆,不是就新建色瘩,否則就直接從getSupportFragmentManager中獲取
myFragment = new MyFragment();
} else {
myFragment = (MyFragment) getSupportFragmentManager().getFragment(savedInstanceState, MyFragment.class.getName());
}
}
這樣再使用myFragment ,就不會出現異常了逸寓!
(花了兩天時間才解決這問題居兆,其實知道病因后也就非常簡單,幾行代碼就搞定竹伸,就是這個排查病因過程是慢慢摸索的泥栖,這里希望給遇到類似問題的小伙伴一些參考,避免浪費不必要的時間Qā0上怼!)