Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android系統教程 >> Android開發教程 >> Android中的Intent Filter簡介

Android中的Intent Filter簡介

日期:2017/2/22 10:09:39      編輯:Android開發教程

Intent是Android應用程序核心組件之間通信和傳遞信息的核心機制。與之相關的IntentFilter也具有相關的安全機制(測試)來進行約束。本文將對其進行詳細介紹。

一、Intent和IntentFilter簡介

一個應用程序的三個核心組件(活動,服務和廣播接收器)都是通過消息即意圖(Intents)來激活的。Intent消息傳送是相同或不同應用中組件運行時晚綁定的一種機制。意圖本身(一個意圖對象)是一個包含被執行操作抽象描述的被動的數據結構。或,對於廣播而言,是某件已經發生並被聲明的事情的描述。存在如下幾種不同的機制來傳送意圖到每種組件中:

一個意圖對象是傳遞給Context.startActivity()或者Activity.startActivityForResult()來啟動一個活動或者讓一個存在的活動去做某些新的事情。

一個意圖對象是傳遞給Context.startService()來發起一個服務或者遞交新的指令給運行中的服務。類似的,一個意圖能被傳遞給Context.bindService() 來在調用組件和一個目標服務之間建立連接。作為一個可選項,它可以發起這個服務如果還沒運行的話。

傳遞給任意廣播方法(例如Context.sendBroadcast(),Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast())的意圖對象被傳遞給所有感興趣的廣播接收者。許多種廣播產生於系統代碼。

在每個例子裡,Android系統找到合適的活動、服務或者一組廣播接收者來回應這個意圖,必要時實例化它們。這些消息傳送系統沒有重疊:廣播意圖僅被傳遞給廣播接收者,永遠不會給活動或者服務。一個傳送給startActivity()的意圖是只會被傳遞給一個活動,永遠不會給一個服務或廣播接收者,如此類推。

為了通知系統它們可以處理哪些意圖,活動、服務和廣播接收器可以有一個或多個意圖過濾器。每個過濾器描述組件的一個能力,一系列組件想要接收的意圖。它實際上按照一個期望的類型來進行意圖濾入,同時濾出不想要的意圖-但是只有不想要的隱式意圖會被濾出(那些沒有命名目標的對象類)。一個顯式意圖總能夠被遞交給它的目標,而無論它包含什麼。這種情況下過濾器不起作用。但是一個顯式意圖僅當它能通過組件的一個過濾器時才可以被遞交到這個組件。

組件為它能做的每項工作,每個呈現給用戶的不同方面分有不同的過濾器。比如,范例記事本應用程序中的主要活動有三個過濾器:一個是空白板,另一個是用戶可以查看、編輯、或選擇的一個指定的記事目錄,第三是在沒有初始目錄說明的情況下查找一個特定的記錄。一個意圖過濾器是IntentFilter類的一個實例。但是,由於Android系統在啟動一個組件前必須知道這個組件的能力,意圖過濾器通常不會用Java代碼來設置,而是在應用程序清單文件(AndroidManifest.xml)中設置<intent-filter>元素。(有一個例外,通過調用Context.registerReceiver()來注冊的廣播接收器的過濾器;它們是作為意圖過濾器對象而被直接創建的。

二 、過濾器與安全Filters and security

我們不能信賴一個意圖過濾器的安全性。當它打開一個組件來接收某些特定類型的隱式意圖,它並不能阻止以這個組件為目標的顯式意圖。即使過濾器對組件要處理的意圖限制某些動作和數據源,總有人能把一個顯式意圖和一個不同的動作及數據源組合在一起,然後命名該組件為目標。

一個過濾器和意圖對象有同樣的動作、數據以及類別字段。一個隱式意圖在過濾器的所有三個方面都被測試。為了遞交到擁有這個過濾器的組件,它必須通過所有這三項測試。即便只有一個不通過,Android系統都不會把它遞交給這個組件。不過,由於一個組件可以包含多個意圖過濾器,一個不能通過其中一個組件過濾器的意圖可能在另外的過濾器上獲得通過。

與之相關的三個測試詳細描述如下:

測試一:動作測試(Actiontest)

清單文件中的意圖過濾器元素裡列舉了動作元素,比如:

<intent-filter. . . >
<action android:name="com.example.project.SHOW_CURRENT"   />
<action android:name="com.example.project.SHOW_RECENT"   />
<action android:name="com.example.project.SHOW_PENDING"   />
. . .
</intent-filter>

如同例子所示,一個意圖對象只對單個動作命名,而一個過濾器可能列舉多個。列表不能為空;一個過濾器必須包含至少一個動作元素,否則它將阻塞所有的意圖。

為了通過這個測試,在意圖對象中指定的動作必須匹配過濾器中所列舉的動作之一。如果意圖對象或過濾器不指定一個動作,結果將是:如果這個過濾器沒有列出任何動作,那意圖就沒有什麼可匹配的,因此所有的意圖都會測試失敗。沒有意圖能夠通過這個過濾器。另一方面,一個未指定動作的意圖對象自動通過這個測試-只要過濾器包含至少一個動作。

測試二:類別測試(Categorytest)

一個意圖過濾器<intent-filter>元素也列舉了類別作為子元素。比如:

<intent-filter. . . >
<category android:name="android.intent.category.DEFAULT"   />
<category android:name="android.intent.category.BROWSABLE"   />
. . .
</intent-filter>

注意前面描述的動作和類別常量沒有在清單文件中使用。相反使用了完整的字符串。比如,對應於前述CATEGORY_BROWSABLE常量,上面的例子裡使用了"android.intent.category.BROWSABLE"字符串。類似的,字符串"android.intent.action.EDIT" 對應於ACTION_EDIT常量。

對一個通過類別測試的意圖,每個意圖對象中的類別必須匹配一個過濾器中的類別。這個過濾器可以列舉另外的類別,但它不能遺漏任何在這個意圖中的類別。

因此,原則上一個沒有類別的意圖對象應該總能夠通過測試,而不管過濾器裡有什麼。絕大部分情況下這個是對的。但有一個例外,Android把所有傳給startActivity()的隱式意圖當作他們包含至少一個類別:"android.intent.category.DEFAULT"(CATEGORY_DEFAULT常量)。 因此,想要接收隱式意圖的活動必須在它們的意圖過濾器中包含"android.intent.category.DEFAULT"。,而帶"android.intent.action.MAIN"和"android.intent.category.LAUNCHER"設置的過濾器是例外。它們標記那些啟動新任務和呈現在啟動屏幕的活動。它們可以在類別列表中包含"android.intent.category.DEFAULT",但不是必要的。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved