??activity的啟動分為顯式調(diào)用和隱式調(diào)用。顯式調(diào)用需要明確指定組件的信息瀑志,來完成調(diào)用涩搓。肩祥。隱式調(diào)用是通過匹配目標(biāo)組件的IntentFilter完成的。一個(gè)組件可以設(shè)置多個(gè)IntentFilter來匹配缩膝。IntentFilter中的過濾信息有action混狠、category、data組成疾层。只有一個(gè)Intent同時(shí)匹配action類別将饺,category類別,data類別才算完全匹配痛黎,才能啟動對應(yīng)的組件予弧。一個(gè)intent只需要匹配任何一組intentFilter就可以啟動對應(yīng)組件。下面一一講解對應(yīng)的匹配規(guī)則湖饱。
一掖蛤、action的匹配規(guī)則
action是一個(gè)字符串,一個(gè)過濾規(guī)則(intentFilter)可以有多個(gè)action井厌。一個(gè)IntentFilter必須有一個(gè)action蚓庭,如果沒有那么則匹配失敗。多個(gè)action只要匹配成功一個(gè)即可匹配成功仅仆,
結(jié)論:
Intent中的action必須存在且必須和過濾規(guī)則中的其中一個(gè)action相同(字符串值完全一樣器赞,區(qū)分大小寫)
二、category的匹配規(guī)則
??category是一個(gè)字符串墓拜,Intent可以沒有category港柜,但是如果一旦有category,不管有幾個(gè)咳榜,每一個(gè)都要能夠和過濾規(guī)則中的任何一個(gè)category相同夏醉。簡而言之,Intent中攜帶Category要全部能和IntentFilter中的Category匹配涌韩。
注意:
系統(tǒng)在調(diào)用startActivity或者startActivityForResult時(shí)畔柔,會默認(rèn)為Intent添加“android.intent.category.DEFAULT"
這個(gè)category。
所以隱式啟動的組件必須包含<category android:name="android.intent.category.DEFAULT" />
??如果Intent中的存在category贸辈,那么這些category都必須和Activity過濾規(guī)則中的category相同释树,才能和這個(gè)Activity匹配。Intent中的category數(shù)量可能少于Activity中配置的category數(shù)量擎淤,但是Intent中的這category必須和Activity中配置的category相同才能匹配奢啥。通俗的講就是,比如Intent中有3個(gè)category嘴拢,activity的過濾規(guī)則中有5個(gè)category桩盲,那intent中的3個(gè)category需要是activity的過濾規(guī)則中有5個(gè)category中的3個(gè),若有任意一個(gè)未出現(xiàn)在這5個(gè)里面席吴,匹配就失敗赌结。
三捞蛋、data的匹配規(guī)則
??Data一般由兩部分組成mimeType和URI。
1. MimeType
??mineType指資源類型包括文本柬姚、圖片拟杉、音視頻等等×砍校可以表示圖片搬设、文本、音視頻等等不同的數(shù)據(jù)格式撕捍。以下是常見文件格式的mimeType拿穴。
<!--常見MimeType-->
<!--音視頻-->
<data android:mimeType="video/*" />
<data android:mimeType="audio/*" />
<!--圖片-->
<data android:mimeType="image/*" />
<!--文本-->
<data android:mimeType="text/*" />
<!--*、bin忧风、class dms默色、exe等-->
<!--<data android:mimeType="application/octet-stream" />-->
<!--pdf-->
<data android:mimeType="application/pdf" />
<!--prf-->
<data android:mimeType="application/pics-rules" />
<!--pot pos ppt-->
<data android:mimeType="application/vnd.ms-powerpoint" />
<!--js-->
<data android:mimeType="application/x-javascript" />
<!--zip-->
<data android:mimeType="application/zip" />
<!--rar-->
<data android:mimeType="application/rar" />
<!--rar-->
<data android:mimeType="application/x-rar-compressed" />
<!--jar-->
<data android:mimeType="application/ava-archive" />
<!--tar-->
<data android:mimeType="application/x-tar" />
<!--tgz-->
<data android:mimeType="application/x-compressed" />
<!--zip-->
<data android:mimeType="application/x-zip-compressed" />
<!--ppt-->
<data android:mimeType="application/vnd.ms-powerpoint" />
<!--xls-->
<data android:mimeType="application/vnd.ms-excel" />
<!--doc、dot-->
<data android:mimeType="application/msword" />
<!--docx-->
<data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
<!--potx-->
<data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.template" />
<!--pptx-->
<data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
<!--xlsx-->
<data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
<!--xltx-->
<data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.template" />
<!--ppsx-->
<data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.slideshow" />
<!--dotx-->
<data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.template" />
如果不知道指定文件的mimeType的話狮腿,可以通過一下方法獲取指定文件的mimeType腿宰。
private static String getMimeType(String filePath) {
String ext = MimeTypeMap.getFileExtensionFromUrl(filePath);
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
}
2. URI
??一個(gè)IntentFilter中可以有多個(gè)data。匹配過程中如果intentFilter含有data那么intent中必須含有data并且只要其中某一個(gè)匹配成功即可認(rèn)為intent匹配成功蚤霞。
??URI具體結(jié)構(gòu)如下:scheme://host:port/(path|pathPrefix|pathPatten)示例如下:
<data
android:scheme="string"
android:host="string"
android:port="1"
android:path="/string"
android:pathPattern="string"
android:pathPrefix="/string"
android:mimeType="string" />
下面一一講解對應(yīng)含義酗失。
- Scheme:URI的模式。即指定的URI的格式昧绣。比如http、content捶闸、file等夜畴,如果沒有指定scheme那么后面的參數(shù)都無效,即整個(gè)URI都無效删壮。
- Host:URI的主機(jī)名贪绘。如www.baidu.com等,如果host未指定那么這個(gè)URI也是無效的央碟。
- port:端口號税灌,僅當(dāng)指定了scheme和host的時(shí)候port才能起作用。
- path:完整的路徑信息亿虽。
- pathPattern:也表示完整的路徑信息菱涤,但是可以包含通配符“",”"表示0或多個(gè)等任意字符洛勉。要注意正則表達(dá)式的規(guī)范粘秆。
- pathPrefix:路徑前綴信息。
注意:調(diào)用方式區(qū)別
??如果同時(shí)存在URI收毫、miemType調(diào)用如下方法:intent.setDataAndType(Uri.parse(""),"image/*");
不能分開調(diào)用intent.setData(Uri.parse(""));和intent.setType("image/*");
因?yàn)檫@兩個(gè)方法是互逆的攻走,調(diào)用一個(gè)會將另一個(gè)置null殷勘,源碼如下:
public @NonNull Intent setType(@Nullable String type) {
mData = null;
mType = type;
return this;
}
public @NonNull Intent setData(@Nullable Uri data) {
mData = data;
mType = null;
return this;
}
隱式調(diào)用注意事項(xiàng)
??隱式調(diào)用啟動組件之前,根據(jù)相應(yīng)的隱式條件信息查詢一下能否匹配到對應(yīng)的組件昔搂。防止直接隱式調(diào)用啟動玲销,發(fā)生錯(cuò)誤,找不到對應(yīng)的組件摘符。判斷方法分為兩種:
- 通過Intent的
intent.resolveActivity(getPackageManager());
方法查詢痒玩。示例如下:
Intent intent=new Intent();
intent.setDataAndType(Uri.parse("http://demo"),"image/*");
intent.resolveActivity(getPackageManager());
- 通過PackageManager的
resolveActivity(Intent intent, @ResolveInfoFlags int flags);
方法查詢。其中第二個(gè)參數(shù)使用PackageManager.MATCH_DEFAULT_ONLY
议慰,匹配那些添加了<category android:name="android.intent.category.DEFAULT"/>
的組件蠢古。如果不使用這個(gè)那么可能匹配到?jīng)]有配置default標(biāo)記的category,從而導(dǎo)致startActivity失敗别凹。建議使用此方法查詢草讶。
Intent intent=new Intent();
intent.setDataAndType(Uri.parse("http://demo"),"image/*");
intent.resolveActivity(getPackageManager());
PackageManager packageManager = getPackageManager();
packageManager.resolveActivity(intent,PackageManager.MATCH_DEFAULT_ONLY);
只要通過以上兩個(gè)方法能夠查詢到對應(yīng)的組件則一定能啟動對應(yīng)的組件。