Android Activity為什麼要細化出onCreate、onStart、onResume、onPause、onStop、onDesdroy這麼多方法讓應用去重載?,oncreateonstart

來源:互聯網
上載者:User

Android Activity為什麼要細化出onCreate、onStart、onResume、onPause、onStop、onDesdroy這麼多方法讓應用去重載?,oncreateonstart
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=6610-17 20:54:42.263: I/com.example.servicetest.AActivity(5817): onStart() 1166919192 taskID=6610-17 20:54:42.263: I/com.example.servicetest.AActivity(5817): onResume() 1166919192 taskID=6610-17 20:54:46.997: I/com.example.servicetest.AActivity(5817): onPause() 1166919192 taskID=6610-17 20:54:47.021: I/com.example.servicetest.BActivity(5817): onCreate() 1166971824 taskID=6610-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onStart() 1166971824 taskID=6610-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onResume() 1166971824 taskID=6610-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的onPause()與onStop()會在什時調用?以及一些問題

第一問:其實那些操作可以放在你所說的方法裡面,你自己實驗,是沒問題的。
第二問:onResume和onPause方法是調用比較頻繁的,在這兩個方法裡面一般做很小耗時的操作,以增強使用者體驗。現在你儲存的那種狀態,手機cpu執行的時間可以基本忽略,因此放在該方法裡也無可厚非。另外:onPause,onStop,onDestory三個方法被標註為YES,由於onPause方法是Activity建立後最有可能保證執行的方法,因此,當系統遇到緊急情況需要恢複記憶體,那麼onStop,onDestory可能不被執行,因此你應當在onPause裡儲存一些至關重要的狀態屬性,當然你應當有選擇性的做一些操作,不能太耗時,如果太耗時,那麼其他的activity將不能被建立直到該activity的onPause方法執行完畢並返回。
第三問:onSaveInstanceState()方法是有個Bundle參數的,就是說這個方法儲存的資料是由系統管理的,當你該activity被殺死,重新訪問的時候該Bundle參數會被傳入onCreate()方法的Bundle。而
在onPause裡面儲存的資料是可能儲存到硬碟去的。
第三點本人沒測過,純屬個人理解。
 
安卓中Activity的onStart()與onResume()的不同是什

首先你要知道Activity的四種狀態:
Active/Runing 一個新 Activity 啟動入棧後,它在螢幕最前端,處於棧的最頂端,此時它處於可見並可和使用者互動的啟用狀態。
Paused 當 Activity 被另一個透明或者 Dialog 樣式的 Activity 覆蓋時的狀態。此時它依然與視窗管理器保持串連,系統繼續維護其內部狀態,所以它仍然可見,但它已經失去了焦點故不可與使用者互動。
Stoped 當 Activity 被另外一個 Activity 覆蓋、失去焦點並不可見時處於 Stoped 狀態。
Killed Activity 被系統殺死回收或者沒有被啟動時處於 Killed 狀態。

protected void onStart() 該方法在 onCreate() 方法之後被調用,或者在 Activity 從 Stop 狀態轉換為 Active 狀態時被調用,一般執行了onStart()後就執行onResume()。
protected void onResume() 在 Activity 從 Pause 狀態轉換到 Active 狀態時被調用。
 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.