1. Intent
Android基本的設計理念是鼓勵減小組件間的耦合,所以Android提供了Intent (意圖) ,
Intent提供了一種通用的消息系統,它容許在你的應用程序與其它的應用程序間傳遞 Intent 來執行動做和產生事件。
使用 Intent 能夠激活 Android 應用的三個核心組件:活動(Activity)、服務(Service)和廣播接收器(BroadcastReceiver)。android
2. 顯式意圖、隱式意圖
Intent能夠劃分紅顯式意圖和隱式意圖。
顯式意圖:調用Intent.setComponent() 或 Intent.setClassName() 或 Intent.setClass()方法明確指定了組件名的Intent爲顯式意圖,顯式意圖明確指定了Intent應該傳遞給哪一個組件。
如: 在 MainActicity 中打開一個新的 Acticity -- OtherActivity
1. Intent intent = new Intent();
2. intent.setComponent(new ComponentName(MainActivity.this, OtherActivity.class));
3. 第二行代碼能夠更換爲:intent.setClass(MainActivity.this, OtherActivity.class);
4. 也能夠使用構造器來指定組件: Intent intent = new Intent(MainActivity.this, OtherActivity.class)
三種 「顯式意圖」 指定方式等價
隱式意圖:沒有明確指定組件名的Intent爲隱式意圖。
Android系統會根據隱式意圖中設置的動做(action)、類別(category)、數據(data: URI和數據類型)找到最合適的組件來處理這個意圖
例如撥打電話的意圖:
Uri uri = Uri.parse("tel:" + phoneCode);
Intent intent = new Intent(Intent.ACTION_CALL, uri);
對於隱式意圖,Android是怎樣尋找到這個最合適的組件呢?記的前面咱們在定義活動時,指定了一個intent-filter,Intent Filter(意圖過濾器)其實就是用來匹配隱式Intent的,當一個意圖對象被一個意圖過濾器進行匹配測試時,只有三個方面會被參考到:動做、數據(URI以及數據類型)和類別。
動做測試(Action test)
一個意圖對象只能指定一個動做名稱,而一個過濾器可能列舉多個動做名稱。若是意圖對象或過濾器沒有指定任何動做,結果將以下:
+ 若是過濾器沒有指定任何動做,那麼將阻塞全部的意圖,所以全部的意圖都會測試失敗。沒有意圖可以經過這個過濾器。
<intent-filter><!-- 空的 --></intent-filter>
+ 另外一方面,只要過濾器包含至少一個動做,一個沒有指定動做的意圖對象自動經過這個測試
類別測試(Category test)
對於一個可以經過類別匹配測試的意圖,意圖對象中的類別必須匹配過濾器中的類別。這個過濾器能夠列舉另外的類別,但它不能遺漏在這個意圖中的任何類別。
原則上一個沒有類別的意圖對象應該總可以經過匹配測試,而無論過濾器裏有什麼。大部分狀況下這個是對的。
但有一個例外,Android把全部傳給startActivity()的隱式意圖看成他們包含至少一個類別:"android.intent.category.DEFAULT" (CATEGORY_DEFAULT常量)。
所以自定義 Activity 的時候,不要覺得光定義一個 action 就夠了。這樣用 startActivity() 來激活這個 Activity 的時候將一直報錯。
緣由就是,他內部要求去匹配 android.intent.category.DEFAULT 這個類別。
所以,想要接收隱式意圖的活動必須在它們的意圖過濾器中包含"android.intent.category.DEFAULT"。
(帶"android.intent.action.MAIN"和"android.intent.category.LAUNCHER"設置的過濾器是例外)
數據測試(Data test)
當一個意圖對象中的URI被用來和一個過濾器中的URI比較時,比較的是URI的各個組成部分。
例如,若是過濾器僅指定了一個scheme,全部該scheme的URIs都可以和這個過濾器相匹配;
若是過濾器指定了一個scheme、主機名但沒有路經部分,全部具備相同scheme和主機名的URIs均可以和這個過濾器相匹配,而無論它們的路經;
若是過濾器指定了一個scheme、主機名和路經,只有具備相同scheme、主機名和路經的URIs才能夠和這個過濾器相匹配。
固然,一個過濾器中的路徑規格能夠包含通配符,這樣只須要部分匹配便可。
數據測試同時比較意圖對象和過濾器中指定的URI和數據類型。規則以下:
a. 一個既不包含URI也不包含數據類型的意圖對象僅在過濾器也一樣沒有指定任何URIs和數據類型的狀況下才能經過測試。
b. 一個包含URI但沒有數據類型的意圖對象僅在它的URI和一個一樣沒有指定數據類型的過濾器裏的URI匹配時才能經過測試。
這一般發生在相似於mailto:和tel:這樣的URIs上:它們並不引用實際數據。
c. 一個包含數據類型但不包含URI的意圖對象僅在這個過濾器列舉了一樣的數據類型並且也沒有指定一個URI的狀況下才能經過測試。
d. 一個同時包含URI和數據類型(或者可從URI推斷出數據類型)的意圖對象能夠經過測試,若是它的類型和過濾器中列舉的類型相匹配的話。
若是它的URI和這個過濾器中的一個URI相匹配或者它有一個內容content:或者文件file: URI並且這個過濾器沒有指定一個URI,那麼它也能經過測試。
換句話說,一個組件被假定爲支持content:和file: 數據若是它的過濾器僅列舉了一個數據類型。
3. 使用隱式意圖
有兩個意圖的過濾器都匹配了某此請求,android 會出現一個列表菜單,供用戶選擇。測試