Activity后台运行一段时间回来crash问题的分析与解决
最近做項目的時候碰到一個棘手的問題,花了不少時間才找到原因并解決。特此記錄這個被我踩過的坑,希望其他朋友遇到此問題不要調到這坑里去了。
問題描述:
? ? ? 1、背景:我的app中某個界面的Activity是繼承FragmentActivity,因為此界面包含兩個Fragment。這里我稱為FragmentA和FragmentB吧。在Activity中有個刷新按鈕,用來刷新ViewPager當前Fragment內容的刷新。點擊Activity的刷新按鈕之后,刷新按鈕需要有簡單的旋轉動畫,等Fragment里面的刷新結束之后,會使用getActivity通知Activity結束刷新按鈕的刷新動畫。以上就是我的業務場景,說簡單點就是Fragment需要與它附屬的Activity進行通信。
2、問題:當應用程序運行到該Activity時,按Home鍵將該應用程序放置后臺運行,去其他app轉轉。一段時間后,又回到該應用程序,還是在之前的那個Activity。這時我想刷新一下Fragment里面的內容,點擊了Activity界面上的刷新按鈕,結果程序crash了。
?
問題分析:
剛開始遇到該問題時,查看奔潰日志,發現是空指針異常。因為這種場景不多,所以只是簡單的加上非空判斷就沒在意這個問題了。到后面換了個測試機器,配置不是很好(只有512M運行內存),結果此問題頻繁地出現,開始引起我的重視了。由于經驗不是很足,此問題不知道怎么重現,所以很難找出問題的根本原因。后來終于在網上找到了一篇和我遇到同樣問題的朋友的帖子,才知道出現這個問題的原因所在。
原來Activity切換到后臺之后,由于內存不夠,此Activity被系統回收了,一段時間之后回到該應用程序,Activity被重新實例化了。而Activity被系統銷毀時,附屬在該Activity的Fragment并沒有被銷毀,在Activity的onSaveInstanceState里面將Fragment狀態保存起來了,所以Activity重新創建了,但是FragmentA和FragmentB還是之前的,而此時FragmentA和FragmentB所附屬的Activity已經被系統回收了,這次再調用getActivity時返回了null,才導致上面問題的出現。
我們看看FragmentActivity源碼中的onSaveInstanceState方法:
1 protected void onSaveInstanceState(Bundle outState) 2 { 3 super.onSaveInstanceState(outState); 4 Parcelable p = mFragments.saveAllState(); 5 if (p != null) { 6 outState.putParcelable("android:support:fragments", p); 7 } 8 }由上面源碼可以看出,FragmentActivity確實在onSaveInstanceState方法里面將Fragment的狀態保存了。
?
問題解決:
知道問題的原因了,就好辦了。解決方法其實很簡單,我們只要讓FragmentActivity被系統回收的時候,不保存Fragment的狀態即可,即在FragmentActivity中重寫onSaveInstanceState方法,并且注釋掉super.onSaveInstanceState(outState)就行了。
1 @Override 2 protected void onSaveInstanceState(Bundle outState) { 3 // super.onSaveInstanceState(outState); 4 }?
總結:
1、程序出現問題時,要先找出出現此問題的原因,對癥下藥才能從根本上解決問題。
2、對于Activity被系統回收導致的問題,可以使用切換橫豎屏來模擬場景。
?
最后感謝寫http://my.oschina.net/u/1011854/blog/469138這篇帖子的朋友。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Activity后台运行一段时间回来crash问题的分析与解决的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 日企将用高空气球把乘客送至25公里高空开
- 下一篇: 微软收购暴雪获力挺,英伟达态度转变签署十