安卓入門筆記之Activity

——本文來自博客園Tekkaman的博客Android之Activity IBM的developerWorks網站張勇詳解Android的Activity組件一文 ,CSDN博客hpoi的博客Android Activity的生命週期 感謝zzxap在CSDN論壇的自問自答——安卓工程運行是如何指定初始頁面的droid工程運行是如何指定初始頁面的前端

Activity

activity類處於android.app包中,繼承體系以下:java

1.java.lang.Objectandroid

2.android.content.Context程序員

3.android.app.ApplicationContext數據庫

4.android.app.Activity網絡

activity是單獨的,用於處理用戶操做。幾乎全部的activity都要和用戶打交道,因此activity類建立了一個窗口,開發人員能夠經過setContentView(View)接口把UI放到activity建立的窗口上,當 activity指向全屏窗口時,也能夠用其餘方式實現:做爲漂浮窗口(經過windowIsFloating的主題集合),或者嵌入到其餘的 activity(使用ActivityGroup)。大部分的Activity子類都須要實現如下兩個接口:app

  • onCreate(Bundle)接口是初始化activity的地方. 在這兒一般能夠調用setContentView(int)設置在資源文件中定義的UI, 使用findViewById(int) 能夠得到UI中定義的窗口.ide

  • onPause()接口是使用者準備離開activity的地方,在這兒,任何的修改都應該被提交(一般用於ContentProvider保存數據).函數

爲了可以使用Context.startActivity(),全部的activity類都必須在AndroidManifest.xml文件中定義有相關的「activity」項。網站

而對於安卓程序須要首先運行的activity即下文提到的「main」activity,則須要AndroidManifest.xml文件中的<intent-filter>元素添加這麼兩句:
<intent-filter>
     <action android:name="android.intent.action.MAIN"/>
     <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>

      <action>元素指定這是一個"main"入口點對這個應用程序。<category>元素指定,這個activity應該被列入系統應用程序列表中(爲了容許用戶啓動這個activity)。

  若是你但願應用程序自包含,而且不但願別的應用程序激活它的activities,那麼你不須要任何其它intent filters。只有一個activity應該有「main"動做和」launcher「分類,就像前面這個例子。你不但願被其它應用程序訪問原Activities應該沒有intent filters並且你能啓動他們經過本身顯示的intent。

  但是,若是你但願你的activity響應影含的intents,從其它應用程序(和你本身的),那麼你必須爲這個activity定義額外的intent filters。每一種你但願響應的類型的intent,你必須包含<intent-filter>,包含<action>元素,可選的,一個<category>元素而且/或一個<data>元素。這些元素指定你的activity能響應的intent的類型。

[若是全部的activity都包含此過濾器(即上面的filter),則默認首個activity爲初始activity]

過濾器使用的具體過程參見如下描述,可幫助記憶和理解:

當寫好的應用發佈到手機上以後,當雙擊」抽屜「裏該應用的圖標時,系統會將這個點擊時間包裝成一個Intent,該Intent包含兩個參數,如上所述的兩個參數被傳遞給應用以後,在應用的功能清單文件中尋找與該意圖匹配的意圖過濾器,若是匹配成功,找到相匹配的意圖過濾器所在的Activity元素,再根據<activity>元素的」name「屬性來尋找其對應的Activity類。接着Android操做系統建立該Activity類的實例對象,對象建立完成以後,會執行到該類的onCreate方法,此onCreate方法是重寫父類Activity的onCreate方法而實現的。onCreate方法用來初始化Activity實例對象。以下是helloWorld.java類中的onCreate方法的代碼:
public void onCreate (Bundle savedInstanceState){
       super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
}

其中super.onCreate(savedInstanceState)的做用是調用其父類Activity的onCreate方法來實現對界面的圖畫繪製工做。在實現本身定義的Activity子類的onCreate方法時必定要記得調用該方法,以確保可以繪製界面。
       setContentView(R.layout.main)的做用是加載一個界面。該方法中傳入的參數是」R.layout.main「,其含義爲R.java類中靜態內部類layout的靜態常量main的值,而改值是一個指向res目錄下的layout子目錄下的main.xml文件的標識符。所以表明着顯示main.xml所定義的畫面

  一個Activity是一個應用程序組件,提供一個屏幕,用戶能夠用來交互爲了完成某項任務,例如撥號、拍照、發送email、看地圖。每個activity被給予一個窗口,在上面能夠繪製用戶接口。窗口一般充滿屏幕,但也能夠小於屏幕而浮於其它窗口之上。

  一個應用程序一般由多個activities組成,他們一般是鬆耦合關係。一般,一個應用程序中的activity被指定爲"main"activity,當第一次啓動應用程序的時候呈現給用戶的那個activity。每個activity而後能夠啓動另外一個activity爲了完成不一樣的動做[該動做經過intent完成,詳見安卓之Activity信使——intent]。每一次一個activity啓動,前一個activity就中止了,可是系統保留activity在一個棧上(「back stack」)。當一個新activity啓動,它被推送到棧頂,取得用戶焦點。Back Stack符合簡單「後進先出」原則,因此,當用戶完成當前activity而後點擊back按鈕,它被彈出棧(而且被摧毀),而後以前的activity恢復。

  當一個activity因新的activity啓動而中止,它被通知這種狀態轉變經過activity的生命週期回調函數。有許多回調函數一個activity可能會收到,源於它本身的狀態變化-不管系統建立它、中止它、恢復它、摧毀它-而且每一個回調提供你完成適合這個狀態的指定工做的機會。例如,當中止的時候,你的activity應該釋聽任何大的對象,例如網絡數據庫鏈接。當activity恢復,你能夠從新得到必要的資源和恢復被中斷的動做。這些狀態轉換都是activity的生命週期的部分。

【Activity 的生命週期】

        和 J2ME 的 MIDlet 同樣,在 android 中,Activity 的生命週期交給系通通一管理。與 MIDlet 不一樣的是安裝在 android 中的全部的 Activity 都是平等的。

*Activity 的狀態及狀態間的轉換

        在 android 中,Activity 擁有四種基本狀態:

  1. Active/Runing一個新 Activity 啓動入棧後,它在屏幕最前端,處於棧[關於Activity棧的概念,可見下文說明]的最頂端,此時它處於可見並可和用戶交互的激活狀態。

  2. Paused 當 Activity 被另外一個透明或者 Dialog 樣式的 Activity 覆蓋時的狀態。此時它依然與窗口管理器保持鏈接,系統繼續維護其內部狀態,因此它仍然可見,但它已經失去了焦點故不可與用戶交互。

  3. Stoped 當 Activity 被另一個 Activity 覆蓋、失去焦點並不可見時處於 Stoped狀態。

  4. Killed Activity 被系統殺死回收或者沒有被啓動時處於 Killed狀態。

        當一個 Activity 實例被建立、銷燬或者啓動另一個 Activity 時,它在這四種狀態之間進行轉換,這種轉換的發生依賴於用戶程序的動做。下圖說明了 Activity 在不一樣狀態間轉換的時機和條件:

  圖 1. Activity 的狀態轉換

圖 1. Activity 的狀態轉換

        如上所示,Android 程序員能夠決定一個 Activity 的「生」,但不能決定它的「死」,也就時說程序員能夠啓動一個 Activity,可是卻不能手動的「結束」一個 Activity。當你調用 Activity.finish()方法時,結果和用戶按下 BACK 鍵同樣:告訴 Activity Manager 該 Activity 實例完成了相應的工做,能夠被「回收」[ 根據下文的意思,應該是調用finish方法時只能使Activity進入Stoped狀態 ]。隨後 Activity Manager 激活處於棧第二層的 Activity 並從新入棧,同時原 Activity 被壓入到棧的第二層,從 Active 狀態轉到 Paused 狀態。例如:從 Activity1 中啓動了 Activity2,則當前處於棧頂端的是 Activity2,第二層是 Activity1,當咱們調用 Activity2.finish()方法時,Activity Manager 從新激活 Activity1 併入棧,Activity2 從 Active 狀態轉換 Stoped 狀態,Activity1. onActivityResult(int requestCode, int resultCode, Intent data)方法被執行,Activity2 返回的數據經過 data參數返回給 Activity1。

*Activity 棧

        Android 是經過一種 Activity 棧的方式來管理 Activity 的,一個 Activity 的實例的狀態決定它在棧中的位置。處於前臺的 Activity 老是在棧的頂端,當前臺的 Activity 由於異常或其它緣由被銷燬時,處於棧第二層的 Activity 將被激活,上浮到棧頂。當新的 Activity 啓動入棧時,原 Activity 會被壓入到棧的第二層。一個 Activity 在棧中的位置變化反映了它在不一樣狀態間的轉換。Activity 的狀態與它在棧中的位置關係以下圖所示:

  圖 2. Activity 的狀態與它在棧中的位置關係

圖 2. Activity 的狀態與它在棧中的位置關係

        如上所示,除了最頂層即處在 Active 狀態的 Activity 外,其它的 Activity 都有可能在系統內存不足時被回收,一個 Activity 的實例越是處在棧的底層,它被系統回收的可能性越大。系統負責管理棧中 Activity 的實例,它根據 Activity 所處的狀態來改變其在棧中的位置。

*與Activity 生命週期相關的方法

在 android.app.Activity類中,Android 定義了一系列與生命週期相關的方法,在咱們本身的 Activity 中,只是根據須要複寫須要的方法,Java 的多態性會保證咱們本身的方法被虛擬機調用,這一點與 J2ME 中的 MIDlet 相似。

 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();
}

這些方法的說明以下:

  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 onPause()在 Activity 從 Active 狀態轉換到 Pause 狀態時被調用。

  4. protected void onStop()在 Activity 從 Active 狀態轉換到 Stop 狀態時被調用。通常咱們在這裏保存 Activity 的狀態信息。

  5. protected void onDestroy()在 Active 被結束時調用,它是被結束時調用的最後一個方法,在這裏通常作些釋放資源,清理內存等工做。

  圖 3. 這些方法的調用時機

圖 3. 這些方法的調用時機

此外,Android 還定義了一些不經常使用的與生命週期相關的方法可用:

 protected void onPostCreate(Bundle savedInstanceState); 
protected void onRestart();
protected void onPostResume();

Android 提供的文檔詳細的說明了它們的調用規則。

【建立一個 Activity】

在 android 中建立一個 Activity 是很簡單的事情,編寫一個繼承自 android.app.Activity的 Java 類並在 AndroidManifest.xml聲明便可。下面是一個爲了研究 Activity 生命週期的一個 Activity 實例(工程源碼見下載):

Activity 文件:

 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> 節點說明 Activity,將 apk 文件安裝後,系統根據這裏的說明來查找讀取 Activity,本例中的說明以下:

 <activity android:name=".EX01" 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】

Activity.startActivity()方法能夠根據傳入的參數啓動另一個 Activity:

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

固然,OtherActivity一樣須要在 AndroidManifest.xml 中定義。[關於intent的內容將在安卓之Activity信使——intent文中介紹

相關文章
相關標籤/搜索