Android 組件 — Activity (創建與啓動)

Android Activity

Activity 簡介

 Activity 是應用程序的四大組件之一,爲用戶提供一個交互界面,比如打電話、發短信、發送郵件等。每一個Activity都會提供一個窗口用於繪製用戶界面。通常窗口都是全屏,但是也可以浮在其他的窗口之上。

 app一般由一個或者多個Activity鬆散耦合在一起。最常見的情況是,一個Activity被指定爲“mian”Activity,作爲用戶啓動app時最先進入的界面。Activity可以啓動其他的Activity界面來滿足不同德操作。每次開啓一個新的Activity時會先關閉當前的Activity,然後將其保存在“Back Stack”(類似先進後出的棧結構),默認情況下,被關閉的Activity會被放在Back Stack中,當用戶按下返回鍵時,以前的Activity會從棧頂彈出並獲得用戶的焦點。(關於Back Stack的部分會在Tasks and Back Stack文檔中詳細討論)

 當一個Activity因爲新開啓一個Activity是被關閉,他會將Activity狀態的變化通知Activity的“生命週期回調”方法。Activity的生命週期被分爲幾個狀態:creation、started、stopped、pause、resume、destroy,每個狀態會對應一個回調方法。系統會在Activity狀態發生改變的時候回調這些方法,這樣你就有機會指定一些適當的代碼。舉個例子,當你關閉一個Activity的時候你必須釋放一些太好內存的對象,比如網絡、數據庫連接等。當Activity恢復時,你可以再次申請那些必要的資源來恢復之前被中斷的操作。

 這篇文章剩餘的部分會討論如何創建和使用一個Activity,包括Activity生命週期的狀態切換,以及如何處理狀態的變換。

Activity的創建


 

 首先你需要創建一個子類來繼承Activity。在子類中需要實現回調方法以提供給系統在不同的狀態下調用,其中最重要的兩個回調函數如下:

onCreate()
這個方法你必須實現。系統在Activity被創建的時候會調用此方法。在此方法中你應用初始化Activity必須用到的資源。最終要的時候你需要調用setContentView()設置Layout文件來填充你的用戶界面。
onPause()
當用戶離開當前的界面時會調用此方法,雖然不一定會終止Activity,但是有可能此界面不會在恢復,所以你需要保存一些用戶的設置,以保證用戶的設置生效。

 還有一些其他的生命週期回調方法,你應該合理的運用這些回調方法,保證在正不同Activity切換和Activity被異常中斷的情況下仍然有一個流暢的用戶體驗,稍後會在Managing the Activity Lifecycle 一節中詳細的討論所有的回調方法。

實現用戶界面

 一個用戶界面由不同級別的視圖(view)組成—view是繼承於View類的對象。每一個視圖都控制者Activity窗口中的一個矩形區域,而且可以與用戶交互。舉個例子,一個視圖可能是一個按鈕,當用戶點擊時可以觸發某個操作。

 Android 提供了許多現成的視圖(view),你可以用來設計和組織你layout(佈局)。“Widgets”是view的別稱,它提供了一個在屏幕可視化的元素,比如一個按鈕(button)、文本框(Text filed)、單選框(checkbox)、或者僅僅是一副圖像(image)。“Layout”繼承於ViewGroup,爲view提供了一個特有的佈局模型,比如線性佈局(LinearLayout)、網格佈局(grid Layout)、相對佈局(relative Layout)。當然,你也可以直接繼承 View 和ViewGroup 類來創建自己的widget和layout,然後應用到Activity的佈局中。

 一般會在app的資源文件中定義一個XML Layout文件。通過這個方法,你可以將Activity的行爲與用戶的界面分開維護。每一個佈局文件都有一個ID,你可以調用setContentView(layout ID)方法爲你的Activity設置佈局文件,你也可以在代碼中(分級式地)創建view並插入到ViewGroup中,然後將ViewGroup作爲layout參數傳遞給setContentView()

 要知道如何創建用戶界面可以參照 User Interface

 在AndroidManifest.xml中聲明Activity

爲了保證系統能夠訪問你的Activity,你需要在AndroidManifest.xml文件中進行聲明。聲明方式如下:打開工程目中的AndroidManifest.xml文件,在<application>元素中添加一個子元素<activity>:

<manifest ... > 
  <application ... > 
      <activity android:name=".ExampleActivity" /> 
      ... 
  </application ... > 
  ... 
</manifest >

<activity>元素下還可以增加其他屬性,比如增加一個標籤、定義Activity的風格或主題。android:name屬性是必須設置的,它指明瞭Activity的類名。一旦你發佈app,你的類名就不能隨意的更改,否則會破壞一些功能,比如已經創建好的app快捷方式,如果你更改了android:name,快捷方式就會失效。(read the blog post, Things That Cannot Change).

 參考 <activity> 可以獲得更詳細的信息。

“intent filter”的使用

 AndroidManifest.xml文件中,爲了方便其他的app能夠激活你的activity,可以在<activity>增加<intent-filter>元素。

 當你用Android SDK tools創建一個app時,它會自動爲你創建一個放在“launcher” 類中的activity的存根,以便響應“main”action,inten filter的使用方式如下:

<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"> 
    <intent-filter> 
        <action android:name="android.intent.action.MAIN" /> 
        <category android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 
</activity>


<action>標識了app的“main”入口,<category>表示activity會被放在系統的ApplicationLauncher中,以便用戶啓動(launch)這個activity。

如果你打算只在當前app中使用該activity,而且不允許其他app激活該activity,那你就不需要任何intent filter。如同上面的例子,只能有一個activity的intent filter 能用戶“main”action和“launcher”category。你不需要其他app訪問的activity則不需要聲明intent filter,該activity所在的app只需要指定activity類名就可以啓動了。

<intent-filter>下也可以增加<category> 和<data>元素。這些元素可以指定你的activity可以響應的intent類型。想了解更多關於activity響應intent的方式,可以參考Intents and Intent Filters

 啓動Activity


你可以調用startActivity((Intent intent, Bundle options))來啓動其他的Activity,intent用於描述想要啓動的Activity。intent可以是明確指定啓動的Activity類名,或者描述你要啓動的動作(系統會根據你的描述爲你選擇一個合適的Activity,甚至從不同app查找也是有可能的)。intent也可以攜帶少量的數據傳遞給需要啓動的Activity。

 在Activity內部啓動當前app中的其他Activity可以直接在intent中指定類名,方式如下:

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

然而,你的app執行的某些操作,比如打電話、發短信、查看地圖,但是你的app可能沒有完成這些功能的Activity,這個時候你可以利用設備上其他具備這些功能的Activity來完成這些操作。intent真正的價值在於,你只需要描述你想要做的操作,系統會自動爲你匹配合適的Activity,如果存在相同功能的Activity的時候,會再提示用戶選擇。舉個例子,如果你允許用戶發郵件,你可以像下面這樣創建一個intent:

Intent intent = new Intent(Intent.ACTION_SEND); 
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray); 
startActivity(intent);

putExtra中recipientArray是一個email 地址的字符串,當帶有email功能的app響應這個intent的時候,它會解析recipientArray中的內容然後放到收件人的地址欄裏。這種情況下,email 發送後會再恢復你之前的Activity。 

Activity 的反饋機制

 有時候,你可能希望啓動的Activity完成操作後能回傳數據。這種情況下,你可以調用startActivityForResult()來啓動Activity(而不是調用startActivity())。爲了能接收Activity處理的結果,你需要實現回調方法:onActivityResult()。當被啓動的Activity推出後會返回一個intent給onActivityResult()

 舉個例子,可能你想要用戶選擇一個聯繫人,然後你的Activity就可以使用聯繫人信息做一些事情。上代碼:

private void pickContact() { 
    // Create an intent to "pick" a contact, as defined by the content provider URI 
    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI); 
    startActivityForResult(intent, PICK_CONTACT_REQUEST); 
} 
 
@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    // If the request went well (OK) and the request was PICK_CONTACT_REQUEST 
    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) { 
        // Perform a query to the contact's content provider for the contact's name 
        Cursor cursor = getContentResolver().query(data.getData(), 
        new String[] {Contacts.DISPLAY_NAME}, null, null, null); 
        if (cursor.moveToFirst()) { // True if the cursor is not empty 
            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); 
            String name = cursor.getString(columnIndex); 
            // Do something with the selected contact's name... 
        } 
    } 
}

這個例子展示了最基本的onActivityResult()用法。返回的數據通過ContentResolver 查詢到contact的Cursor。更詳細的信息可以參考Content Providers

轉載請註明出處:http://blog.csdn.net/jack_chen_00/article/details/9771569

發佈了28 篇原創文章 · 獲贊 0 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章