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請求的能力——組件希望接收什麼類型的請求行為,什麼類型的請求數據。