我的位置: 首頁 > 學習專區 > 安卓技術 >
就業喜報更多 >
熱點專題更多 >
熱門標簽更多 >
Android: Activity 生命周期
時間:2014-02-12 15:39:00   來源: 東莞北大青鳥,東莞電腦培訓
大家都在關注:Android: Activity
分享到:
[導讀] Activity生命周期 運行、暫停、停止。運行(獲得了焦點)、暫停(失去了焦點、但是可見)、停止(失去了焦點、不可見)。中間有可見、不可
Activity生命周期 運行、暫停、停止。

運行(獲得了焦點)、暫停(失去了焦點、但是可見)、停止(失去了焦點、不可見)。中間有可見、不可見生命周期。前臺生命周期。

1
2
3
4
5
6
7
8
public class OurActivity extends Activity {
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
}

Activity 周期圖\

在上圖中,Activity有三個關鍵的循環:

整 個的生命周期,從onCreate(Bundle)開始到onDestroy()結束。Activity在onCreate()設置所有的“全局”狀態, 在onDestory()釋放所有的資源。例如:某個Activity有一個在后臺運行的線程,用于從網絡下載數據,則該Activity可以在 onCreate()中創建線程,在onDestory()中停止線程。
可見的生命周期,從onStart()開始到onStop()結束。在這段時間,可以看到Activity在屏幕上,盡管有可能不在前臺,不能和用戶交 互。在這兩個接口之間,需要保持顯示給用戶的UI數據和資源等,例如:可以在onStart中注冊一個IntentReceiver來監聽數據變化導致 UI的變動,當不再需要顯示時候,可以在onStop()中注銷它。onStart(),onStop()都可以被多次調用,因為Activity隨時可 以在可見和隱藏之間轉換。
前臺的生命周期,從onResume()開始到onPause()結束。在這段時間里,該Activity處于所有Activity的最前面,和用戶進行 交互。Activity可以經常性地在resumed和paused狀態之間切換,例如:當設備準備休眠時,當一個Activity處理結果被分發時,當 一個新的Intent被分發時。所以在這些接口方法中的代碼應該屬于非常輕量級的。

 

      1. protected void onCreate(Bundle savedInstanceState)一個 Activity 的實例被啟動時調用的第一個方法。一般情況下,我們都覆蓋該方法作為應用程序的一個入口點,在這里做一些初始化數據、設置用戶界面等工作。大多數情況下,我們都要在這里從 xml 中加載設計好的用戶界面。例如:
 setContentView(R.layout.main);

 

當然,也可從 savedInstanceState中讀我們保存到存儲設備中的數據,但是需要判斷savedInstanceState是否為 null,因為 Activity 第一次啟動時并沒有數據被存貯在設備中:

 if(savedInstanceState!=null){
 savedInstanceState.get("Key");
 }

 

      1. protected void onStart()該方法在 onCreate() 方法之后被調用,或者在 Activity 從 Stop 狀態轉換為 Active 狀態時被調用。
      2. protected void onResume()在 Activity 從 Pause 狀態轉換到 Active 狀態時被調用。
      3. protected void onResume()在 Activity 從 Active 狀態轉換到 Pause 狀態時被調用。
      4. protected void onStop()在 Activity 從 Active 狀態轉換到 Stop 狀態時被調用。一般我們在這里保存 Activity 的狀態信息。
      5. protected void onDestroy()在 Active 被結束時調用,它是被結束時調用的最后一個方法,在這里一般做些釋放資源,清理內存等工作。
      6. 創建一個 Activity在 android 中創建一個 Activity 是很簡單的事情,編寫一個繼承自android.app.Activity的 Java 類并在 AndroidManifest.xml聲明即可。下面是一個為了研究 Activity 生命周期的一個 Activity 實例(工程源碼見下載):Activity 文件:
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        public class EX01 extends Activity {
        private static final String LOG_TAG = EX01.class.getSimpleName();
        @Override
        public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Log.e(LOG_TAG, "onCreate");
        }
        @Override
        protected void onStart() {
        Log.e(LOG_TAG, "onStart");
        super.onStart();
        }
        @Override
        protected void onResume() {
        Log.e(LOG_TAG, "onResume");
        super.onResume();
        }
        @Override
        protected void onPause() {
        Log.e(LOG_TAG, "onPause");
        super.onPause();
        }
        @Override
        protected void onStop() {
        Log.e(LOG_TAG, "onStop");
        super.onStop();
        }
        @Override
        protected void onDestroy() {
        Log.e(LOG_TAG, "onDestroy ");
        super.onDestroy();
        }
        }

        AndroidManifest.xml 中通過 節點說明 Activity,將 apk 文件安裝后,系統根據這里的說明來查找讀取 Activity,本例中的說明如下:

         
        	 
        		 
        		 
        	 
         

        回頁首

        啟動另外一個 Activity

        Activity.startActivity()方法可以根據傳入的參數啟動另外一個 Activity:

         Intent intent =new Intent(CurrentActivity.this,OtherActivity.class);
         startActivity(intent);

        當然,OtherActivity同樣需要在 AndroidManifest.xml 中定義。

        回頁首

        Activity 之間通信

        使用 Intent 通信

        在 Android 中,不同的 Activity 實例可能運行在一個進程中,也可能運行在不同的進程中。因此我們需要一種特別的機制幫助我們在 Activity 之間傳遞消息。Android 中通過 Intent 對象來表示一條消息,一個 Intent 對象不僅包含有這個消息的目的地,還可以包含消息的內容,這好比一封 Email,其中不僅應該包含收件地址,還可以包含具體的內容。對于一個 Intent 對象,消息“目的地”是必須的,而內容則是可選項。

        在上面的實例中通過 Activity. startActivity(intent)啟動另外一個 Activity 的時候,我們在 Intent 類的構造器中指定了“收件人地址”。

        如果我們想要給“收件人”Activity 說點什么的話,那么可以通過下面這封“e-mail”來將我們消息傳遞出去:

        1
         

        那么“收件人”該如何收信呢?在 OtherActivity類的 onCreate()或者其它任何地方使用下面的代碼就可以打開這封“e-mail”閱讀其中的信息:

         Intent intent =getIntent();// 收取 email
         Bundle bundle =intent.getBundleExtra("key");// 打開 email
         bundle.getBoolean("boolean_key");// 讀取內容
         bundle.getString("string_key");

        上面我們通過 bundle對象來傳遞信息,bundle維護了一個 HashMap對象,將我們的數據存貯在這個 HashMap 中來進行傳遞。但是像上面這樣的代碼稍顯復雜,因為 Intent 內部為我們準備好了一個 bundle,所以我們也可以使用這種更為簡便的方法:

        1
        2
        3
        4
        Intent intent =new Intent(EX06.this,OtherActivity.class);
        intent.putExtra("boolean_key", true);
        intent.putExtra("string_key", "string_value");
        startActivity(intent);

        接收:

         Intent intent=getIntent();
         intent.getBooleanExtra("boolean_key",false);
         intent.getStringExtra("string_key");

        使用 SharedPreferences

        SharedPreferences 使用 xml 格式為 Android 應用提供一種永久的數據存貯方式。對于一個 Android 應用,它存貯在文件系統的 /data/ data/your_app_package_name/shared_prefs/目錄下,可以被處在同一個應用中的所有 Activity 訪問。Android 提供了相關的 API 來處理這些數據而不需要程序員直接操作這些文件或者考慮數據同步問題。

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        // 寫入 SharedPreferences
        SharedPreferences preferences = getSharedPreferences("name", MODE_PRIVATE);
        Editor editor = preferences.edit();
        editor.putBoolean("boolean_key", true);
        editor.putString("string_key", "string_value");
        editor.commit();
         
        // 讀取 SharedPreferences
        SharedPreferences preferences = getSharedPreferences("name", MODE_PRIVATE);
        preferences.getBoolean("boolean_key", false);
        preferences.getString("string_key", "default_value");

        其它方式

        Android 提供了包括 SharedPreferences 在內的很多種數據存貯方式,比如 SQLite,文件等,程序員可以通過這些 API 實現 Activity 之間的數據交換。如果必要,我們還可以使用 IPC 方式。

        Activity 的 Intent Filter

        Intent Filter 描述了一個組件愿意接收什么樣的 Intent 對象,Android 將其抽象為 android.content.IntentFilter 類。在 Android 的 AndroidManifest.xml 配置文件中可以通過 節點為一個 Activity 指定其 Intent Filter,以便告訴系統該 Activity 可以響應什么類型的 Intent。

        當 程序員使用 startActivity(intent) 來啟動另外一個 Activity 時,如果直接指定 intent 了對象的 Component 屬性,那么 Activity Manager 將試圖啟動其 Component 屬性指定的 Activity。否則 Android 將通過 Intent 的其它屬性從安裝在系統中的所有 Activity 中查找與之最匹配的一個啟動,如果沒有找到合適的 Activity,應用程序會得到一個系統拋出的異常。這個匹配的過程如下:
        圖 4. Activity 種 Intent Filter 的匹配過程
        圖 4. Activity 種 Intent Filter 的匹配過程
        Action 匹配

        Action 是一個用戶定義的字符串,用于描述一個 Android 應用程序組件,一個 Intent Filter 可以包含多個 Action。在 AndroidManifest.xml 的 Activity 定義時可以在其節點指定一個 Action 列表用于標示 Activity 所能接受的“動作”,例如:

         
         
         
        ……
         

        如果我們在啟動一個 Activity 時使用這樣的 Intent 對象:

         Intent intent =new Intent();
         intent.setAction("com.zy.myaction");

        那么所有的 Action 列表中包含了“com.zy.myaction”的 Activity 都將會匹配成功。

        Android 預定義了一系列的 Action 分別表示特定的系統動作。這些 Action 通過常量的方式定義在 android.content. Intent中,以“ACTION_”開頭。我們可以在 Android 提供的文檔中找到它們的詳細說明。

        URI 數據匹配

        一個 Intent 可以通過 URI 攜帶外部數據給目標組件。在 節點中,通過節點匹配外部數據。

        mimeType 屬性指定攜帶外部數據的數據類型,scheme 指定協議,host、port、path 指定數據的位置、端口、和路徑。如下:

         

        如果在 Intent Filter 中指定了這些屬性,那么只有所有的屬性都匹配成功時 URI 數據匹配才會成功。

        Category 類別匹配

        節點中可以為組件定義一個 Category 類別列表,當 Intent 中包含這個列表的所有項目時 Category 類別匹配才會成功。

         

        一些關于 Activity 的技巧

        鎖定 Activity 運行時的屏幕方向

        Android 內置了方向感應器的支持。在 G1 中,Android 會根據 G1 所處的方向自動在豎屏和橫屏間切換。但是有時我們的應用程序僅能在橫屏 / 豎屏時運行,比如某些游戲,此時我們需要鎖定該 Activity 運行時的屏幕方向,節點的android:screenOrientation屬性可以完成該項任務,示例代碼如下:

         // 豎屏 , 值為 landscape 時為橫屏
        …………
         

        全屏的 Activity

        要使一個 Activity 全屏運行,可以在其 onCreate()方法中添加如下代碼實現:

         // 設置全屏模式
         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
         // 去除標題欄
         requestWindowFeature(Window.FEATURE_NO_TITLE);

        在 Activity 的 Title 中加入進度條

        為了更友好的用戶體驗,在處理一些需要花費較長時間的任務時可以使用一個進度條來提示用戶“不要著急,我們正在努力的完成你交給的任務”。如下圖:

        在 Activity 的標題欄中顯示進度條不失為一個好辦法,下面是實現代碼:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        // 不明確進度條
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        setContentView(R.layout.main);
        setProgressBarIndeterminateVisibility(true);
         
        // 明確進度條
        requestWindowFeature(Window.FEATURE_PROGRESS);
        setContentView(R.layout.main);
        setProgress(5000);



         
      7.  
好操吊精彩视视频 亚洲成av人片在线观看