文章目錄
- 概述
- 如何建立Activity
- 實現使用者介面
- 在名單檔案中聲明activity
- 使用intent過慮器
- 啟動一個Activity
- 啟動一個acitvity並得到結果
- 關閉Activity
概述
Activities 是一個程式的組件之一。它的主要功能是提供介面。
一個程式一般由多個Activity組成,各activities之間關係很鬆散,它們之間沒有直接的關聯。必須有一個activity被指定為主activity,它是程式啟動時首先顯示的介面。每個activity都可以隨意啟動其它的activity。每當一個activity被啟動,則前一個activity就被停止。一個程式中的所有啟動的activity都被放在一個棧中,所以被停止的activity並沒有銷毀,而在存於棧中。新啟動的activity先被存放於棧中,然後獲得輸入焦點。在當前活動的activity上點返回鍵,它被從棧中取出,然後銷毀,然後上一個activity被恢複。
當一個activity因為新的activity啟動而被停止時,它會收到狀態變化的通知,這樣的變化有多個,每個都會引起系統調用一個相應的回調方法以通知activity,這些回調方法被統稱為“生命週期回調方法”。這些回調方法分別在Activity被建立、停止、恢複、銷毀時被調用。
如何建立Activity
1 從類activity繼承。
2 實現“生命週期回調方法”
兩個最重要的方法是:
onCreate()--這個是必須實現的函數,在其中做初始化工作。記住:你必須在此函數中調用setContentView()函數的設定Activity的介面。
onPause()--這個雖然很重要,但不是要必須實現的。此函數在使用者離開Activity時被調用(這一般並不表示Activity要被銷毀了)。在這個函數中,你一般需要提交那些需儲存狀態的資料(因為使用者可能不再返回到這個Activity)。
其它回調方法視情況實現。
實現使用者介面
此處的使用者介面指的就是activity上的控制項們。所有的控制項都從View類派生,所以可以把它們都稱為View。每個控制項佔據一個矩形地區。
控制項又分為以下兩類:Widgets是完成特定功能的控制項,比如button,text field,checkbox 等。Layouts是容納Widgets控制項並進行排版的控制項,當然,Layout中還可以容納Layout。Widgets從View類派生,Layouts從ViewGroup類中派生,開發人員可以從View或ViewGroup派生創造自己的控制項。
定義介面的最好的方法是使用XML格式的layout檔案,它作為資源儲存在工程中,可以在工程的res/layout下面找到這些XML檔案。通過這種方式就做到了代碼與界分離。把layout 下的某個XML設定為某個Activity的介面,需調用Activity的setContentView(),把XML的資源ID作為參數傳入即可。
在名單檔案中聲明activity
為了能讓系統操作你的Activity,你必須在工程的名單檔案中聲明它。例如:
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
...
</manifest >
當然有很多屬性可以設定給Activity,比如label,icon或主題等等。詳情請查看<activity>元素的說明。
注意看<activity android:name=".ExampleActivity"/>,看到activity name的值中,最前面有個”.”,如果你把它忘了,程式運行就會出錯,而你很難找出錯誤的原因。其次,不論你是Activity是只內部使用還是外部使用,都要去名單檔案中註冊,否則依然會出現莫名其妙的錯誤,只是在內部使用時,不需要為acitivity增加意圖過濾器。
使用intent過慮器
可以為一個<activity>元素指定多個過慮器。使用<intent-filter>元素指定。intent過慮器的目的是告訴其它組件如何啟動這個Activity。當你使用ADT建立一個新工程時,根Activity被自動建立,它已具有兩個意圖過慮器,一個意圖過慮器聲明這個Activity負責響應“main”action;另一個過慮器聲明這個Activity須被置於”launcher”類別之下。一般是這個樣子:
<activityandroid:name=".ExampleActivity"android:icon="@drawable/app_icon">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<intent-filter>中就是過濾器們。<action>說明此Acitivity是程式的”main”入口,<category>指出這個Acitivity需要在系統的應用列表中列出。
如果你寫的程式中的Activity不需被其它程式調用,那麼不需為這個Activity增加任何意圖過濾器。但程式中必須有一個Activity被指定為”main” Action和”launcher” category。你自己程中的 Activity可以用更直接的方式調用。
然而,如果你想讓你的Activity被其它程式調用,那麼你需要為它增加意圖過濾器。這些過意圖濾器包括<action>,<category>以及<data>。這些元素指明了你的activity響應何種類型的intent。
啟動一個Activity
你可以用startActivity()啟動一個activity,它有一個參數是intent,你需要在這個intent中指明要調用的activity。Intent中你可以明確地指定要啟動的activity,或只指定activity的類型,此時系統會為你挑選一個合適的activity,這個activity可能位於其它程式中,也可能位於你自己的程式中。Intent中可以帶一坨被新activity使用的資料(相當於參數傳遞)。
在你的程式內部,如果需要啟動一個內部的activity,你需在intent中明確指定新activity的類名。例如:
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
SignInActivity是要啟動的activity類。
然而,你的程式可能想執行自身沒有提供的功能,比如發出郵件,傳送簡訊息等。此時,需要啟動其它程式提供的activity。此時就體現出intent的真正價值來了:它可以很容易地啟動其它程式提供的activity,你只需要在intent中指定你要執行的動作,然後調用 startActivity() ,系統就會跟據你的需要,為你選擇一個合適的activity,並啟動它。如果同時有多個activity可以執行這動作,那麼使用者可以選擇哪個被使用。例如,你想讓使用者發送一個電子郵件,你可以建立以下的Intent:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
putExtra()是設定擴充資料的,.EXTRA_EMAIL表明第二個參數recipientArray裡面放的是多個email地址。當發郵件的程式被啟動並接收到這個intent時,它就把郵件地址們放到它的Acitivity介面的“to”控制項中。當使用者發送完畢返回時,你的activity就恢複運行(resume)。可以看到,啟動另外一個程式是多麼的容易。
啟動一個acitvity並得到結果
有時,你可能想從你啟動的activity獲得其執行後返回的結果。此時你可以用方法startActivityForResult()來啟動新acitivity(不再是startActivity了)。然後,你的程式還需要定義回調方法onActivityResult()。當新activity運行結束時,它把一個intent返回給你的程式,這個intent是在onActivityResult()中被接收。
例如:你想讓使用者開啟通訊錄,從中選擇一個連絡人,然後你取得使用者所選的連絡人,對之進行處理。以下是範例程式碼:
private void pickContact() {
//Create anintent 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, intresultCode, Intent data) {
// If the requestwent well (OK) and the request was PICK_CONTACT_REQUEST
if (resultCode== Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
// Perform aquery to the contact's content provider for the contact's name
Cursorcursor = getContentResolver().query(data.getData(),new String[]{Contacts.DISPLAY_NAME}, null, null, null);
if(cursor.moveToFirst()) { // True if the cursor is not empty
intcolumnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
String name =cursor.getString(columnIndex);
// Dosomething with the selected contact's name...
}
}
}
此例子展示了在onActivityResult()中的基本邏輯流程。首選檢查所啟動的Activity是否正確運行,resultCode為Activity.RESULT_OK表示正常,其次,查看requestCode是否與當時請求的一致,即是否為PICK_CONTACT_REQUEST。都通過後,開始操作返回的資料,也就是data參數。
Data是這樣處理的,用ContentResolver向內容提供者發出請求,這個請求會返回一個遊標,通過這個遊標讀取資料,這很像資料庫表的操作。要理解此處,請查閱Content Providers一節。
關閉Activity
Activity可以內部調用finish()方法關閉它自己,也可以調用finishActivity()方法關閉其它的activity。
注意:大多數情況下,你不應主動結束一個activity。系統掌管著activity的生命,所以你也不必結束自己的activity。使用上述方法會破壞使用者體驗。除非你覺得很必要時,否則就不要做!