Intent的構成html
Intent能夠帶有action,data(由URI表達),extra data(key/value map,鍵值對),指定的類名(成爲component name)。一個intent至少攜帶上述的一個內容。java
Action。Action名,在上一筆記中已經給出兩種例子,一種是系統自帶的,如Intent.ACTION_DAIL,一種是開發者經過AndroidManifest.xml進行註冊的,在建立intent時給出:Intent intent=new Intent(String action_name);。action_name字符串的名字前綴是類名。android
Data。由不一樣action決定有效的URI的格式。intent.setData(Uri.parse(」xxxxxx」));。被喚起的activity能夠同activity.getIntent()來得到intent,而後通該intent的getData()來獲取數據。app
//觸發方。 //被觸發方。須要在AndroidManifest.xml中在intent-filter中註冊data信息,後文詳細說明 Intent intent = this.getIntent(); String data = intent.getData(); |
通用的action即數據傳遞。Action和喚起的並不是是一對一的,例如Intent.ACTION_VIEW根據data,喚起不一樣的應用。這種一對多,也就是通用的action,在manifest中註冊時,須要聲明數據(URI)的要求。具體能夠參考:http://developer.android.com/guide/topics/manifest/data-element.html。ACTION_VIEW是經過schema進行區分。經過class名字、action名字等方式進行指定的稱爲explicit intent,能夠一對多的稱爲implicit intent。ui
<activity......>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http"/>
<data android:scheme="https"/>
</intent-filter>
</activity>this
若是咱們本身的intent要傳遞data,也必需要在manifest中註冊data,不然intent會喚起失敗,報告ActivityNotFoundException的異常。google
比較經常使用的還有MIME type,例如註冊<data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />表示要查看notes的集合(即目錄),而註冊<data android:mimeType="vnd.android.cursor.item/vnd.google.note" />則表示查看具體item,即查看具體的note。spa
擴展數據(Extra data)傳遞。uri的方式限制了信息的傳遞量。Extra的格式key/value對,key名字一般以包名開頭,而value能夠是任何基礎數據類型,或者是實現android.os.Parcelable的對象。.net
在IntentTestDemo.java(經過intent i喚起IntentBasicViewActivity)經過下面傳遞extra數據。
一、extra數據以bundle的方式在intent中存放,若是已經有bundle,將新的鍵值對加入其中,若是沒有bundle,則建立一個。將來確保key的惟一性
二、key名一般以包名開頭,本例以常量方式,實際爲:cn.flowingflying.android.pro.extra.string。
三、下面是最最簡單據類型,還能夠是array,例如putExtra(String name, int[] values);
能夠是Serializable對象,如putExtra(String name, Serializable value);以及Parcelable對象,如putExtra(String name,Parcelable value); 。
能夠將bundle進行傳遞,如putExtra(String name, Bundle value);,
能夠將Intent進行傳遞,如putExtra(String name, Intent anotherIntent);
能夠支持Array list:如putIntegerArrayListExtra(String name, ArrayList arrayList); putParcelableArrayListExtra(String name, ArrayList arrayList);和putStringArrayListExtra(String name, ArrayList arrayList)
【注意】在intent中傳遞的不是reference(指針),而是copy一份,咱們修改對象,並不會影響已經copy進intent中bundle的數據,這點須要很是注意。
i.putExtra(IntentBasicViewActivity.EXTRA_FLOWINGFLYING_STRING, "Hello, Intent! ");
在IntentBasicViewActivity.java中經過如下代碼獲取extra數據。
Intent intent = this.getIntent();
Bundle b = intent.getExtras();
String s = b.getString(EXTRA_FLOWINGFLYING_STRING));
Android系統有已定義的key值,具體參見http://developer.android.com/reference/android/content/Intent.html#EXTRA_ALARM_COUNT
使用Component來喚起Activity
以前例子,咱們經過action name來喚起Activity。對於explicit intent,即明確指定調用哪一個activity,能夠經過給出該Component的的package name和class name來進行調用。下面咱們試驗採用四種相似的方式進行調用,這四種方式本質沒有區別。
private void basicTest1(){ //要寫完整的class Name,不能寫IntentBasicViewActivity或者.IntentBasicViewActivity,不然報告找不到Activity的錯誤 private void basicTest4(){ |
Intent的Category屬性
在AndroidManifest.xml中,咱們能夠設置intent的category,例如:
<activity ……>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
在應用啓動是,將尋找Activity標記爲CATEGORY_LAUNCHER來加載。Android定義了多個Category,具體能夠在http://developer.android.com/reference/android/content/Intent.html#CATEGORY_ALTERNATIVE中查閱。例如CATEGORY_HOME能夠做爲該應用的home screen,而CATEGORY_GADGET適合嵌入到某個activity中。
下面是兩個例子。例子1指明瞭action name,因爲存在多個匹配,系統將列出來,供用戶進行選擇,以下。
例子2在例子1的基礎上增長了intent.addCategory(Intent.CATEGORY_LAUNCHER);,增長對Category名字的匹配,能夠看到系統進行了進一步的過濾。:
咱們能夠經過PackageManager在代碼中,能夠不喚起intent就得到匹配的activity信息。以下
Intent intent = new Intent(Intent.ACTION_MAIN,null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
PackageManager pm = getPackageManager();
List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
for(ResolveInfo ri : list){
String packageName = ri.activityInfo.packageName;
String className = ri.activityInfo.name;
... ....
//有了packageName和className,就能夠進行分析,而後經過Intent i= new Intent(packaname,className); startActivity(i);喚起咱們所需的acitivity。
}
然而,經過PackageManager得到匹配的Activity的數量多於例子中系統提供給用戶選擇的activities的數量,爲什麼?特別是沒有將本應用顯示出來。經過category篩選屬於implicit intent的調用方式,不屬於指定軟件包名及類名的explicit intent的精確調用方式,對於implicit intent調用須要進行聲明,以下:
<activity android:name="……" android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
activity的intent-filter中能夠有多個category描述,其中CATEGORY_DEFAULT表示可使用implicit intent調用,當咱們增長此項聲明後,本應用就出如今匹配的activity列表中。一樣,對於經過action name來調用的,不指定包名和類名的,也屬於implicit intent,一樣須要進行CATEGORY_DEFAULT的聲明,不然會出現ActivityNotFoundException的錯誤。若是activity沒有在intent fliter中設置爲CATEGORY_DEFAULT,咱們能夠用PackageManager獲取匹配的activities的信息,分析後獲得確切的包名和類名,經過explicit的方式喚起該activity。
此外Android說若是從launcher screen喚起時不須要DEFAULT,也就是此時acitivty只需MAIN和LAUNCHER,固然咱們也能夠DEFAULT設上。Android在DEFAULT上彷佛有些繁雜,簡單說若是咱們不但願App被其餘App經過implicit調用,咱們就不要設置DEFAULT。
在category中有一個有趣的類別:<category android:name="android.intent.category.HOME"/>,咱們在MainActivity以及另一個Activity增長該類別。
<application ...... >
<activity ...... >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name=".IntentBasicViewActivity" android:label="@string/intent_basic_test">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
......
</application>
左圖在代碼中經過PackageManager來查看匹配CATEGORY_HOME的信息;中圖經過StartActivity(intent)來喚起匹配CATEGORY_HOME的Activities時,系統給予用戶的選擇,若是在應用中按Home鍵,有一樣效果;右圖爲退出應用,按Home鍵,要求進入Home UI時,系統給予用戶的選擇。
相關連接: 個人Android開發相關文章