Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?
原創鏈接:http://blog.csdn.net/zhao_3546/article/details/12843477,轉載請注明,謝謝。
最近在研究Activity的啟動流程,老羅的blog在看,也找了其它資料學習,也跟過Android4.3的源碼,
在跟代碼的過程中,突然想到下面的這個問題:
? ? Android Activity為什么要細化出onCreate、onStart、onResume、onPause、onStop、onDesdroy這么多方法讓應用去重載?
網上太多根據Android開發規范翻譯轉載的內容,都不是我想要的答案,那就自己分析下。
如下是一段典型的Activity間切換的日志,從AActivity切換到BActivity:
10-17 20:54:42.247: I/com.example.servicetest.AActivity(5817): onCreate() 1166919192 taskID=66 10-17 20:54:42.263: I/com.example.servicetest.AActivity(5817): onStart() 1166919192 taskID=66 10-17 20:54:42.263: I/com.example.servicetest.AActivity(5817): onResume() 1166919192 taskID=66 10-17 20:54:46.997: I/com.example.servicetest.AActivity(5817): onPause() 1166919192 taskID=66 10-17 20:54:47.021: I/com.example.servicetest.BActivity(5817): onCreate() 1166971824 taskID=66 10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onStart() 1166971824 taskID=66 10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onResume() 1166971824 taskID=66 10-17 20:54:47.099: I/com.example.servicetest.AActivity(5817): onStop() 1166919192 taskID=66
當觸發從AActivity切換到BActivity時的日志如下:
10-17 20:54:46.997: I/com.example.servicetest.AActivity(5817): onPause()?1166919192 taskID=66
10-17 20:54:47.021: I/com.example.servicetest.BActivity(5817): onCreate()?1166971824 taskID=66
10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onStart()?1166971824 taskID=66
10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onResume()?1166971824 taskID=66
10-17 20:54:47.099: I/com.example.servicetest.AActivity(5817): onStop()?1166919192 taskID=66
先AActivity的onPause()被調用,然后是BActivity的初始化流程(onCreate() -->?onStart() -->?onResume()),再然后是AActivity的onStop()被調用。
有點意思,為什么不是先AActivity的onPause()、onStop()被調用,然后再BActivity的初始化流程(onCreate() -->?onStart() -->?onResume())?
或者又為什么不是先BActivity的初始化流程(onCreate() -->?onStart() -->?onResume()),再AActivity的onPause()、onStop()被調用?
如果所有的初始化都在onCreate()中實現,會有什么問題?
? ? 首先,Activity的onCreate()被調用時,Activity還不可見,如果要做一些動畫,既然視圖還不存在,在onCreate中來啟動動畫,明顯有問題;
? ? 其次,AActivity 切換到 BActivity,再切換到 AActivity(我們假定是AActivity的同一個實例),由于實例已經存在,所以onCreate不會再被調用,那AActivity從后臺切換至前臺時,有可能需要一些初始化,那就沒法再被調用到了,也有問題;
如果所有的初始化都在onStart()中實現,會有什么問題?
? ? 首先,onCreate()注釋中,是明確建議?setContentView()、findViewById()?要在?onCreate() 中被調用,但我實測了一下,在onStart()中調用?setContentView()、findViewById() 功能也是正常的;
? ? 其次,onStart() 被調用時,Activity可能是可見了,但還不是可交互的,onResume()的注釋中都明確地說了這不是Activity對用戶是可見的最好的指示器,onStart() 在這之前被調用,那有一些特殊的初始化相關的邏輯在這里被調用也會有問題。
如果把所有的去初始化都在onStop()中實現,會有什么問題?
??? 1、 在?onResume()?的注釋中,建議是在onResume()中打開獨占設備(比如相機),與onResume()對應的是onPause(),所以所有的去初始化操作放在onStop()中執行,可能會引出新的問題;
??? 2、onStop()?的注釋中明確地寫了,在內存不足而導致系統無法保留此進程的情況下,onStop() 可能都不會被執行。
??? 我的老Android手機的相機應用如果未正常關閉,相機在不重啟系統的情況下就無法再正常啟動,估計就和這個機制有關;相機進程是被強制殺掉的,而導致去初始化操作未被正常執行。
?
Activity間跳轉時,為什么是先AActivity的onPause()被調用,然后是BActivity的初始化流程(onCreate() -->?onStart() -->?onResume()),再然后是AActivity的onStop()被調用?
??? 1、在?onResume()?的注釋中,建議是在onResume()中打開獨占設備(比如相機),與onResume()對應的是onPause(),關閉相機的操作也應該在此方法中被調用;否則,考慮一下如下場景:
??????? 如果AActivity打開了相機,我們點擊某按鈕要跳轉到BActivity中,BActivity也想打開相機;假設AActivity的onPause() 在 BActivity啟動后再被調用,
??????? 那BActivity根本就無法再正常啟動相機。
??? 2、onPause() 的注釋中,也明確地說了,在這個方法中執行停止動畫等比較耗CPU的操作,如果不先執行這些操作,就先啟動新應用,然后再來執行此操作,確實是不合邏輯;
?
從AActivity切換到BActivity的日志如下:
10-17 20:54:46.997: I/com.example.servicetest.AActivity(5817): onPause()?1166919192 taskID=66
10-17 20:54:47.021: I/com.example.servicetest.BActivity(5817): onCreate()?1166971824 taskID=66
10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onStart()?1166971824 taskID=66
10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onResume()?1166971824 taskID=66
10-17 20:54:47.099: I/com.example.servicetest.AActivity(5817): onStop()?1166919192 taskID=66
從邏輯的完整性和用戶體驗的角度來分析,這樣實現確實是比較合理的,當用戶觸發某事件切換到新的Activity,用戶肯定是想盡快進入新的視圖進行操作,
上面已經說了,在onResume()一般會打開獨占設備,開啟動畫等,
當需要從AActivity切換到BActivity時,先執行AActivity中的與onResume()相對應的onPause()操作,比如關閉獨占設備,關閉動畫,或其它耗費cpu的操作;
以防止BActivity也需要使用這些資源,關閉耗CPU的操作,也有利于BActivity運行的流暢。
底層執行AActivity的onPause()時,有一定的時間限制的,當ActivityManagerService通知應用進程暫停指定的Activity時,如果對應的onPause()在500ms內還沒有執行完,ActivityManagerService就會強制關閉這個Activity。如下就是對應的onPause()執行超時常量定義:
// How long we wait until giving up on the last activity to pause. This// is short because it directly impacts the responsiveness of starting the// next activity.static final int PAUSE_TIMEOUT = 500; // 定義在ActivityStack.java中
AActivity中比較消耗資源的部分關閉后,再切換到BActivity中執行BActivity的初始化,顯示BActivity中的View。
當BActivity已經執行顯示出來了,用戶可以交互,后臺再去執行AActivity的onStop()操作,即使這里面有些比較耗時的操作,也沒有關系,這是在后臺執行所以也不影響用戶的體驗。
總結
以上是生活随笔為你收集整理的Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Utils.toDip()的用法
- 下一篇: android三种载入图片方式