Android學習筆記-Intent(一)
Intent對象在Android官方API這樣描述:It is a passive data structure holding an abstract description of an operation to be performed. 它是一種資料結構,抽象描述一次將要被執行的操作,其作用是在程式運行過程中串連兩個不同的組件。 Intent機制的引入,是實現Android應用程式的組件間通訊的一種訊息機制,它允許你在應用程式的組件間傳遞 Intent 來執行動作和產生事件,組件可以是跨應用程式間傳遞訊息。Intent的設計目的也是為了減少Android應用程式的組件間的耦合。 Intent可以理解為不同組件的通訊媒介或者意圖。Intent訊息可以啟用Android程式的三大核心組件:Activity,Service和BroadcastReceiver。 Intent的用法如下: 一.Intent在Activity中的應用: 1.Intent的組成部分: Intent對象由以下六個部分組成:Component name、Action、Data、Category、Extras、Flags。 2.Intent的樣本: 傳遞一個Intent對象到 Context.startActivity(intent) 或者 Activity.startActivity ForResult(int) 去運行一個Activity(可以在通過此方式啟動後的Activity中調用 Activity.setResult() 設定結果參數,該參數將會在啟動當前activity的activity中被接收---可以通過onActivityResult(int requestCode, int resultCode, Intent data) 接收)。 a.無返回參數的樣本: android.content.Intent requestIntent = new android.content.Intent(OrginalActivity.class, DestinationActivity.class); startActivity(requestIntent); b.有返回參數的樣本: 複製代碼 public class OrginalActivity extends Activity { public void onCreate(Bundle saveInstanceState) { super.onCreate(saveInstanceState); final android.content.Intent requestIntent = new android.content.Intent(OrginalActivity.class, DestinationActivity.class); findViewById(R.id.button).setOnClickListener ( new OnClickListener() { public void onClick(View v) { startActivityForResult(requestIntent, RequestCode); } } ); } protected void onActivityResult(int requestCode, int resultCode,Intent intent) { if (requestCode == RequestCode && resultCode == ResultCode ) { Bundle ret = intent.getExtras(); If (ret!=null) { TextView textView = (TextView) findViewById(R.id.textView01); textView.setText(ret.getString(“key”)); } } else { // 其他條件的執行代碼 } } } // end of class definition Public class DestinationActivity extends Activity { public void onCreate(Bundle saveInstanceState) { super.onCreate(saveInstanceState); findViewById(R.id.button1).setOnClickListener ( new OnClickListener() { public void onClick(View v) { android.content.Intent resultIntent = new android.content.Intent(); resultIntent.putExtras(“key”, “values”); setResult(ResultCode,resultIntent); finish(); } } ); } }複製代碼3.Intent-Action 指明一個意圖的動作,通常Action分為系統定義Action和自訂Action. a.Intent裡面定義的Action常量為系統Action如下: b.自訂Action可以如下所示: 複製代碼<activity android:name=".OrginalActivity"> <intent-filter> <action android:name="selectAction"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> 複製代碼 c.補充:android.intent.action.MAIN的意義 android.intent.action.MAIN標記了啟動Application時先啟動那個Activity,若有多個android.intent.action.MAIN,則先啟動mainfest裡面第一個出現的android.intent.action.MAIN。如果mainfest檔案裡註冊的有多個Activity都有<Intent Filters>標籤,指定 action android:name="android.intent.action.MAIN",則系統預設啟動Activity列表中從上到下第一個Activtiy. 4.Intent Resolution(解析意圖) 在我們的應用程式內,我們需要在一個Activity跳轉到另外一個Activity的時候,我們會通過封送Intent訊息,我們在Action中指明跳轉的Activity的包名+類名,我們可以實現到另外一個Activity的跳轉。這個時候的Activity之間的跳轉,我們封送的Intent就是顯式意圖(explicit intent)。所以,顯一般在應用程式內使用。 我們還會有這樣一種情況,我們不知道我們要跳轉的Activity組件的具體名稱,也就是我們沒有一個明確的Activity來處理我們的動作,我們只是知道我們需要處理我們動作的Activity需要滿足什麼條件,android系統必須找到最適合的組件去處理這個intent。這個時候,我們的Intent意圖所指定的篩選條件,會去篩選在我們的Android系統所有註冊的滿足條件的Activity,然後,通常會讓我們去選擇我們需要用哪個Activity去處理我們的動作。這種情況下我們封送的Intent就是隱式意圖(implicit Intent)。在此我們引出Intent Filters 來解釋我們的意圖過濾過程。 5.Intent Filters IntentFilter對象負責過濾掉組件無法響應和處理的Intent,只將自己關心的Intent接收進來進行處理。 IntentFilter實行“白名單”管理,即只列出組件樂意接受的Intent,但IntentFilter只會過濾隱式Intent,顯式的Intent會直接傳送到目標組件。 Android組件可以有一個或多個IntentFilter,每個IntentFilter之間相互獨立,只需要其中一個驗證通過則可。除了用於過濾廣播的IntentFilter可以在代碼中建立外,其他的IntentFilter必須在AndroidManifest.xml檔案中進行聲明。IntentFilter中具有和Intent對應的用於過濾Action,Data和Category的欄位。 a.一個Intent對象只能設定一個Action,但是一個Activity的IntentFilter可以有多個Action。封送的Intent訊息只要滿足其中一個Action,就可以滿足條件。如果Intent 訊息沒有包含具體的 action 行為定義,只要過濾器規則中定義一條 action 行為描述,則該過濾器匹配 Intent 訊息; b.Intent 訊息沒有包含任何 URI 資料或者具體資料內容的資訊,僅能匹配不包含任何資料過濾資訊的過濾器;Intent 中沒有提供資料類型,系統將從資料中推算資料類型。Intent 訊息中推算的資料類型如果包含在過濾器規則中聲明的資料類型列表時,該訊息匹配該過濾器,否則該訊息將會被過濾器過濾. 如果一個Intent對象包含資料類型,但不包含URI:僅當Intentfilter也沒指定URL,而只包含資料類型且與Intent相同,才通過檢測。 如果一個Intent對象既包含URI,也包含資料類型(或資料類型能夠從URI推斷出),只有當其資料類型匹配Intentfilter中的資料類型,並且通過了URL檢查時,該Intent對象才能通過檢查。 其中URL由四部分組成:它有四個屬性scheme、host、port、path對應於URI的每個部分。 例如:content://com.wjr.example1:121/files scheme部分:content host部分:com.wjr.example1 port部分:121 path部分:files host和port部分一起構成URI的憑據(authority),如果host沒有指定,那port也會被忽略。 這四個屬性是可選的,但他們之間並不是完全獨立的。要讓authority有意義,scheme必須要指定。要讓path有意思,scheme和authority必須指定。 Intentfilter中的path可以使用萬用字元來匹配path欄位,Intent和Intentfilter都可以用萬用字元來指定MIME類型。 c.Intentfilter中可以設定多個Category,Intent中也可以含有多個Category,只有Intent中的所有Category都能匹配到Intentfilter中的Category,Intent才能通過檢查。也就是說,如果Intent中的Category集合是Intentfilter中Category的集合的子集時,Intent才能通過檢查。如果Intent中沒有設定Category,則它能通過所有Intentfilter的Category檢查。 如果一個Intent能夠通過不止一個組件的Intentfilter,使用者可能會被問那個組件被啟用。如果沒有目標找到,會產生一個異常。 總結一下,應用程式的組件為了告訴Android自己能響應、處理哪些隱式Intent請求,可以聲明一個甚至多個IntentFilter。每個 IntentFilter描述該組件所能響應Intent請求的能力——組件希望接收什麼類型的請求行為,什麼類型的請求資料。