2025-02-10

Starting an Activity [啟動一個Activity]

不像其他編程范式一樣:程序從main()方法開始啟動。Android系統根據生命周期的不同階段喚起對應的回調函數來執行代碼。系統存在啟動與銷毀一個activity的一套有序的回調函數。
這一個課會介紹那些生命周期中最重要的回調函數,並演示如何處理啟動一個activity所涉及到的回調函數。
Understand the Lifecycle Callbacks [理解生命周期的回調]

在一個activity的生命周期中,系統會像金字塔模型一樣去調用一系列的生命周期回調方法。Activity生命周期的每一個階段就像金字塔中的臺階。當系統創建瞭一個新的activity實例,每一個回調函數會向上一階的移動activity狀態。金字塔頂端意味著activity是跑在最前端的並且用戶可以與它進行交互。
當用戶開始離開這個activity, 為瞭卸載這個activity,系統會調用其它方法來向下一階移動activity狀態。在某些情況下,activity會隱藏在金字塔下等待 (例如當用戶切換到其他app), 這個時候activity可以重新回到頂端 (如果用戶回到這個activity) 並且恢復用戶離開時的狀態。
Figure 1. 下面這張圖講解瞭activity的生命周期:[顯然,這個金字塔模型要比之前Dev Guide裡面的生命周期圖更加容易理解,更加形象]

 

根據你的activity的復雜度,你也許不需要實現所有的生命周期方法。然而,你需要知道每一個方法的功能並確保你的app能夠像用戶期望的那樣執行。如何實現一個符合用戶期待的app,你需要註意下面幾點:

當使用你的app的時候,不會因為有來電通話或者切換到其他app而導致程序crash。
當用戶沒有激活某個組件的時候不要消耗寶貴的系統資源。
當離開你的app並且一段時間後返回,不要丟失用戶的使用進度。
當設備發送屏幕旋轉的時候,不會crash或者丟失用戶的使用進度。
在下面的課程中會介紹上圖所示的幾個生命狀態。然而,其中隻有三個狀態是靜態的,這三個狀態下activity可以存在一段比較長的時間。[其它幾個狀態會很快就切換掉,停留的時間比較短暫]
Resumed:在這個狀態,activity是在最前端的,用戶可以與它進行交互。(通常也被理解為"running" 狀態)
Paused:在這個狀態,activity被另外一個activity所遮蓋:另外的activity來到最前面,但是半透明的,不會覆蓋整個屏幕。被暫停的activity不會再接受用戶的輸入且不會執行任何代碼。
Stopped:在這個狀態, activity完全被隱藏,不被用戶可見。可以認為是在後臺。當stopped, activity實例與它的所有狀態信息都會被保留,但是activity不能執行任何代碼。
其它狀態 (Created and Started) 都是短暫的,系統快速的執行那些回調函數並通過執行下一階段的回調函數移動到下一個狀態。也就是說,在系統調用 onCreate() , 之後會迅速調用onStart(), 之後再迅速執行 onResume().
上面就是基本的activity生命周期。
Specify Your App's Launcher Activity [指定你的程序首次啟動的Activity]

當用戶從主界面點擊你的程序圖標時,系統會調用你的app裡面的被聲明為"launcher" (or "main") activity中的 onCreate() 方法 。這個Activity被用來當作你的程序的主要進入點。
你可以在AndroidManifest.xml, 中定義哪個activity作為你的主activity。
這個main activity必須在manifest使用包括 MAIN action and LAUNCHER category 的 <intent-filter> 標簽來聲明。例如:
[html]
<activity android:name=".MainActivity" android:label="@string/app_name"> 
    <intent-filter> 
        <action android:name="android.intent.action.MAIN" /> 
        <category android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 
</activity> 
<activity android:name=".MainActivity" android:label="@string/app_name">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
如果你的程序中沒有一個activity聲明瞭 MAIN action 或者 LAUNCHER category ,那麼在設備的主界面列表裡面不會呈現你的app圖標。
Create a New Instance [創建一個新的實例]

大多數app都包括許多不同的activities,這樣使得用戶可以執行不同的動作。無論這個activity是創建的主activtiy還是為瞭響應用戶行為而新創建的,系統都會調用新的activity實例中的onCreate()方法。
你必須實現onCreate()方法來執行程序啟動所需要的基本邏輯。
例如:下面的onCreate() 方法演示瞭為瞭建立一個activity所需要的一些基礎操作。如,聲明UI元素,定義成員變量,配置UI等。[onCreate裡面盡量少做事情,避免程序啟動太久都看不到界面]
[java]
TextView mTextView; // Member variable for text view in the layout  
 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
 
    // Set the user interface layout for this Activity  
    // The layout file is defined in the project res/layout/main_activity.xml file  
    setContentView(R.layout.main_activity); 
     
    // Initialize member TextView so we can manipulate it later  
    mTextView = (TextView) findViewById(R.id.text_message); 
     
    // Make sure we're running on Honeycomb or higher to use ActionBar APIs  
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
        // For the main activity, make sure the app icon in the action bar  
        // does not behave as a button  
        ActionBar actionBar = getActionBar(); 
        actionBar.setHomeButtonEnabled(false); 
    } 

TextView mTextView; // Member variable for text view in the layout

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Set the user interface layout for this Activity
    // The layout file is defined in the project res/layout/main_activity.xml file
    setContentView(R.layout.main_activity);
   
    // Initialize member TextView so we can manipulate it later
    mTextView = (TextView) findViewById(R.id.text_message);
   
    // Make sure we're running on Honeycomb or higher to use ActionBar APIs
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        // For the main activity, make sure the app icon in the action bar
        // does not behave as a button
        ActionBar actionBar = getActionBar();
        actionBar.setHomeButtonEnabled(false);
    }
}

一旦結束onCreate 操作,系統會迅速調用 onStart() 與 onResume() 方法。你的activity不會在Created 或者 Started 狀態停留。技術上來說,activity在onStart()被調用後會開始被用戶可見,但是 onResume() 會迅速被執行使得activity停留在Resumed狀態,直到一些因素發生變化才會改變這個狀態。 例如接受到一個來電,用戶切換到另外一個activity,或者是設備屏幕關閉。 www.aiwalls.com
在後面的課程中,你講看到其他方法是如何使用的, onStart() 與 onResume() 在用戶從Paused or Stopped 狀態中恢復的時候非常有用。
Note:  onCreate() 方法包含瞭一個參數叫做savedInstanceState ,這將會在後面的課程:重新創建一個activity的時候涉及到。

 

Figure 2. 上圖顯示瞭onCreate(), onStart(), and onResume().是如何執行的。當這三個順序執行的回調函數完成後,activity會到達Resumed狀態。
Destroy the Activity [銷毀Activity]

activity的第一個生命周期回調函數是 onCreate(), 它最後一個回調是 onDestroy(). 系統會執行這個方法作為你的activity要從系統中完全移除的信號。
大多數 apps 並不需要實現這個方法,因為局部類的references會被destroyed並且你的activity應該在 onPause() 與 onStop()中執行清除的操作。 然而,如果你的activity包含瞭你在onCreate時創建的後臺線程,或者是其他有可能導致內存泄漏的資源,你應該在OnDestroy()時殺死他們。
[java]
@Override 
public void onDestroy() { 
    super.onDestroy();  // Always call the superclass  
     
    // Stop method tracing that the activity started during onCreate()  
    android.os.Debug.stopMethodTracing(); 

@Override
public void onDestroy() {
    super.onDestroy();  // Always call the superclass
   
    // Stop method tracing that the activity started during onCreate()
    android.os.Debug.stopMethodTracing();
}
Note: 系統通常是在執行瞭 onPause() and onStop() 之後再調用 onDestroy() ,除非你的程序裡面再其他地方調用瞭 finish() 方法,這樣系統會直接就調用onDestory方法,其它生命周期的方法則不會被執行。

 

摘自 四方城南

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *