Canxa0notxa0roid異常:p…
我在一個(gè)android項(xiàng)目的開發(fā)階段一直運(yùn)行良好,直到上線前夕,在一個(gè)android項(xiàng)目中運(yùn)行。 4.03系統(tǒng)的手機(jī)運(yùn)行卻給出了一些異常,產(chǎn)生force close:java.lang.IllegalStateException: Can not perform this action after onSaveInstance!
先了解一下我項(xiàng)目的一些基本概況,UI結(jié)構(gòu)是TabActivity包含5個(gè)Tabs,每個(gè)Tab是另一個(gè)單獨(dú)的Activity。
android發(fā)生了異常 在4.03系統(tǒng)中,當(dāng)我在一個(gè)Tab上按下Back鍵時(shí),我會(huì)給出java。.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
整個(gè)異常發(fā)生的過程都是從logout中發(fā)現(xiàn)的:
代碼Java
1. Can not perform this action after onSaveInstanceState
2. android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1109)
3. android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:399)
4. android.app.Activity.onBackPressed(Activity.java:2066)
5. android.app.Activity.onKeyUp(Activity.java:2044)
6. android.view.KeyEvent.dispatch(KeyEvent.java:2529)
7. android.app.Activity.dispatchKeyEvent(Activity.java:2274)
8. com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
9. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
10. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
11. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
12. com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
13. com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
14. android.app.Activity.dispatchKeyEvent(Activity.java:2269)
15. com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
16. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
17. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
18. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
19. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
20. android.widget.TabHost.dispatchKeyEvent(TabHost.java:297)
21. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
22. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
23. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
24. com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
25. com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
26. android.app.Activity.dispatchKeyEvent(Activity.java:2269)
27. com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
28. android.view.ViewRoot.deliverKeyEventPostIme(ViewRoot.java:2880)
29. android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2853)
30. android.view.ViewRoot.handleMessage(ViewRoot.java:2028)
31. android.os.Handler.dispatchMessage(Handler.java:99)
32. android.os.Looper.loop(Looper.java:132)
33. android.app.ActivityThread.main(ActivityThread.java:4028)
34. java.lang.reflect.Method.invokeNative(Native Method)
35. java.lang.reflect.Method.invoke(Method.java:491)
36. com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
37. com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
38. dalvik.system.NativeStart.main(Native Method)
上面的異常信息表明,我寫的類不是異常的根源。根據(jù)異常信息,Can not perform this action after onSaveInstanceState,可知異常原因:在onSaveInstanceState行為之后,app執(zhí)行了一個(gè)無法響應(yīng)的行為,導(dǎo)致了異常。
在信息at android.app.Activity.onBackPressed(Activity.java:2066),這個(gè)說法表明異常發(fā)生在響應(yīng)返回鍵響應(yīng)事件的行為上。當(dāng)我們按下返回鍵時(shí),我們會(huì)對(duì)activity實(shí)施的響應(yīng)進(jìn)行研究:onKeyDown-->onBackPressed-->onPause->onStop->onDestroy。
什么時(shí)候?qū)嵤?dǎo)火索onSaveInstanceState?
讓我們先看看android。 API的一段原文:
代碼Java
1. 首先看看Application Fundamentals上的一段話:
2.
3. Android calls onSaveInstanceState() before the activity becomes vulnerable to being destroyed by the system, but does not bother calling it when the instance is actually being destroyed by a user action
4. as pressing the BACK key)
從上面可以知道,當(dāng)一個(gè)activity變得“容易”并被系統(tǒng)銷毀時(shí),除非activity被客戶主動(dòng)銷毀,例如當(dāng)客戶按下BACK鍵時(shí),activity的onSaveInstanceState就會(huì)被執(zhí)行。
請(qǐng)注意上面的雙引號(hào),什么是“簡單”?不言而喻,activity還沒有被銷毀,只是一個(gè)概率。
onSaveInstanceState的調(diào)用遵循一個(gè)重要原則,即當(dāng)系統(tǒng)“未經(jīng)您的許可”銷毀您的activity時(shí),onSaveInstanceState將被系統(tǒng)調(diào)用,這是系統(tǒng)的職責(zé),因?yàn)樗仨殲槟峁┮粋€(gè)存儲(chǔ)您數(shù)據(jù)的機(jī)會(huì)。
那么為什么在項(xiàng)目中響應(yīng)onBackPressed事件時(shí)會(huì)給出上述異常呢?這也說明是after onSaveInstanceState?
這是因?yàn)槲襎ab中的Activity響應(yīng)了onBackPressed事件,task必須彈出,TabActivity作為它的父器皿,當(dāng)然也要彈出task,TabActivity 變得“容易”被系統(tǒng)破壞,于是調(diào)用onSaveInstanceState存儲(chǔ)狀態(tài)。
現(xiàn)在整個(gè)過程都很清楚,但這一切都很正常。這個(gè)過程也符合Activity的生命周期。為什么會(huì)報(bào)告異常?或者最新的安卓 4.03出了問題,難道不是說系統(tǒng)不兼容嗎?
對(duì)!
經(jīng)過網(wǎng)上查看,發(fā)現(xiàn)API 11 上述一些控件,包括Fragment和ActivityGroup,正在調(diào)用。saveInstanceState有一個(gè)bug,也許是google。已經(jīng)修改了saveInstanceState的實(shí)現(xiàn)。
直到原因隱藏在后面,解決問題的思路就出來了:讓父器皿TabActivityonDestroy在不調(diào)用saveInstanceState的情況下onDestroy
在tab上方的activity監(jiān)控BACK鍵事件,響應(yīng)并阻止,然后通過廣播方式通知父器皿TabActivity,主動(dòng)銷毀自己,從而達(dá)到應(yīng)對(duì)onBackPressed退出App的效果。
本文僅代表作者觀點(diǎn),版權(quán)歸原創(chuàng)者所有,如需轉(zhuǎn)載請(qǐng)?jiān)谖闹凶⒚鱽碓醇白髡呙帧?/p>
免責(zé)聲明:本文系轉(zhuǎn)載編輯文章,僅作分享之用。如分享內(nèi)容、圖片侵犯到您的版權(quán)或非授權(quán)發(fā)布,請(qǐng)及時(shí)與我們聯(lián)系進(jìn)行審核處理或刪除,您可以發(fā)送材料至郵箱:service@tojoy.com


