Activity的生命周期


      今天對於Activity的生命周期又有了一點深入的理解。做個總結吧。

一、正常情況下的生命周期

     什么叫正常情況下的生命周期呢?也就是我們經常了解的一個活動的正常的生命流程。不用過度解釋,

總結如下:

 

(1)onCreate()方法

 

活動第一次創建時被調用。

 

(2)onStart()

 

活動由不可見變為可見的時候調用

 

(3)onResume()

 

當活動准備開始與用戶交互時會觸發該方法,一般只會在需要執行以下的操作時才重寫該事件:

 

l 開始動畫

 

l 開始監聽GPS更新

 

l 顯示一些相關的提示和對話框

 

l 注冊廣播監聽

 

4onPause()

 

系統准備去啟動或者恢復另外一個活動的時候調用。或者當活動被切換到后台時將觸發該方法,一般我們需要在該事件做如下的事情:

 

l 保存用戶未提交的數據

 

l 關閉或清除引用的資源

 

l 注銷廣播

 

l 如果存在正在顯示的提示或者對話框,則必須利用.Dismiss()進行清除。

 

5onStop()

 

當該活動完全不可見的時候被調用。一般會由以下原因觸發:

 

l 當一個新的活動打開,並覆蓋該活動時

 

l 一個已存在的活動切換到前台時

 

l 活動被銷毀時

 

 

 

OnStop不是每次都會被執行,如果內存低下時,系統將不會執行該事件,而是直接關閉該應用,所以大家在OnPause事件中就要保存好所以的參數等等。而不能依賴該事件。

 

(6)onDestroy()

 

活動銷毀之前被調用

 

7onRestart()

 

當活動由停止狀態變為運行狀態時被調用。即當用戶通過Home按鈕將該用戶切換到后台,並在之后又打開該應用則會觸發該事件。一般也很少重寫該方法。

 

 

     貼一張大家都知道的流程圖吧,如下:

 

 

 

 

 

    需要極其注意的是:在onPause中執行的操作不能太耗時!

 

二、異常情況下活動的生命周期

      這個是重點要說的!什么是異常情況呢?不好說,比如因為資源相關的配置發生改變或者系統內存不足時,活動就

會被殺死。這就屬於異常情況,總之一句話:活動被異常終止!最常見的就是下面的兩種情況:

(1)橫屏或者豎屏切換時。此時因為切換之間系統要對活動中的布局里面的圖片進行更換(比如你可能會准備同樣的兩張

      圖片,不同像素寬高,分別對應於橫屏或者豎屏的情況),此時就會導致在切換時,活動被瞬間殺死又被瞬間重建!

(2)因為系統內存不足,活動被回收時。

      發生意外終止,系統做出的對策就是會將活動中的數據進行自動保存,然后再需要的時候再將活動創建出來恢復數據。

     因此,對應的生命周期如下圖:

 

     也就是說在發生意外時,系統會自動調用onSaveInstanceState方法來保存數據,在需要的時候再會重新創建出這個活動,

然后自動調用onRestoreInstanceState方法來恢復數據。你可能會有疑問,一個活動中可能有一個TextView,還有一個按鈕,

可能還有其他的,那么當活動意外終止,怎么來控制保存這些控件的數據呢?其實任何一個view都重寫了onSaveInstanceState

和onRestoreInstanceState方法,你可以翻看源碼,看看發生意外時,每一個view都會自動保存什么。這里不再多說。

 

     上面列出的兩種意外情況下的活動的生命周期是一樣的,都是如上圖所示。系統內存不足,不好模擬。但是橫屏和豎屏

比較好模擬。下面我們通過一個實際例子,來看看是不是真的如上面所述的那樣。

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

     新建一個項目。修改其Manifest文件,加入橫豎和豎屏切換的感應,如下:

 

 <activity
            android:name=".MainActivity"
            android:label="@string/app_name" android:screenOrientation="sensor"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

 

 

 

     上面只貼出了修改的那段代碼,黃色部分就是加入的自動切換橫屏和豎屏的功能。

     下面再修改其MainActivity代碼,如下:

 

 1 public class MainActivity extends ActionBarActivity {
 2 
 3     private static final String Tag = "MainActivity";
 4 
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_main);
 9 
10         if(savedInstanceState != null)
11         {
12             String t = savedInstanceState.getString("save_test");
13             Log.e(Tag,t+"   "+"onCreate");
14         }
15 
16     }
17 
18     @Override
19     protected void onSaveInstanceState(Bundle outState) {
20         super.onSaveInstanceState(outState);
21 
22         String t = "save me  ";
23         Log.e(Tag,t+"onSaveInstanceState");
24         outState.putString("save_test",t);
25     }
26 
27     @Override
28     protected void onRestoreInstanceState(Bundle savedInstanceState) {
29         super.onRestoreInstanceState(savedInstanceState);
30 
31         String t = savedInstanceState.getString("save_test");
32         Log.e(Tag,t+"    "+"onRestoreInstanceState");
33     }
34 
35  
36 }

 

 

 

    代碼中重寫了onSaveInstanceState和onResoreInstanceState方法,然后就在各個方法中打印標簽。

   下面運行一下程序,做如下的操作:

 

 

     也就是控制手機,做了一個橫豎和豎屏的切換。我們來看一下打印結果,如下:

     通過打印結果,就會發現在橫屏和豎屏切換時,確實是調用了保存數據和恢復數據的那些方法。而從再一次

調用了onCreate方法,就知道活動被重建了。

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

    接着上面的分析,有沒有方法讓在橫豎和豎屏切換時,不要重新創建活動呢??當然是肯定的。

其實很簡單,只要在Manifest文件中加入configChanges屬性即可。也就是當檢測到confiChanges指定

的屬性發生改變時,也不會再去重新創建活動了

 

 

       下面我們就修改代碼,來測試一下。首先修改Manifest中的代碼,如下:

 <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="sensor" android:configChanges="orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

 

       可以看到,添加了一句(即黃色部分),即檢測到方向發生改變或者屏幕的size改變,也不去重新創建活動。

這針對的就是橫屏和豎屏的切換。

     然后修改MainActivity中的代碼,如下:

 

 1 public class MainActivity extends ActionBarActivity {
 2 
 3     private static final String Tag = "MainActivity";
 4 
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_main);
 9 
10         if(savedInstanceState != null)
11         {
12             String t = savedInstanceState.getString("save_test");
13             Log.e(Tag,t+"   "+"onCreate");
14         }
15 
16     }
17 
18     @Override
19     protected void onSaveInstanceState(Bundle outState) {
20         super.onSaveInstanceState(outState);
21 
22         String t = "save me  ";
23         Log.e(Tag,t+"onSaveInstanceState");
24         outState.putString("save_test",t);
25     }
26 
27     @Override
28     protected void onRestoreInstanceState(Bundle savedInstanceState) {
29         super.onRestoreInstanceState(savedInstanceState);
30 
31         String t = savedInstanceState.getString("save_test");
32         Log.e(Tag,t+"    "+"onRestoreInstanceState");
33     }
34 
35  @Override 36     public void onConfigurationChanged(Configuration newConfig) { 37         super.onConfigurationChanged(newConfig); 38         Log.e(Tag,"onConfigurationChanged"); 39  } 40 }

 

 

 

      黃色部分是我們新增加的代碼。然后運行程序,依然做一個橫屏豎屏的切換操作,打印結果如下:

 

     我們這次只有onConfiguration這一個方法被調用。onSaveInstanceState方法和onRestoreInstanceState方法

都沒有被調用,onCreate方法也沒有,即沒有再重新創建活動了。這提示我們,如果在橫豎屏切換過程中,還想做一些

邏輯操作的話,可以放在onConfiguration方法中。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

總結:(1)系統只在異常終止了Activity時,才會調用onSaveInstanceState和onRestoreInstanceState方法

               來恢復數據。因此我們可以重寫這兩個方法來防止活動被出現意外終止時,數據發生丟失。

         (2)如果使用了在Manifest文件中加入configChanges屬性來監測發生變化時不再重新創建活動,那么

               onConfiguration方法會被自動回調,我們可以在這里實現相關邏輯。

         (3)就是上面的兩張圖,一個正常活動生命周期的圖,一個異常下活動生命周期的圖。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM