一个比较生僻却会引起奇特现象的知识点,
intent-filter里data的匹配是组合形式的匹配方式
同级的data里的scheme,authority, path数据分别组成一个数组,
array_scheme, array_ authority, array_ path,
可匹配的uri必须在array_scheme array_ authority array_ path 的笛卡尔积中
对于
<data
android:scheme="ftp"
android:host="details"
android:path="">
</data>
<data
android:scheme="http"
android:host="*"
android:pathPattern="/.*/api"
>
</data>
可以匹配的组合为
scheme | host | path |
"ftp" | "details" | "" |
"ftp" | "details" | "/.*/api" |
"ftp" | "*" | "" |
"ftp" | "*" | "/.*/api" |
"http" | "details" | "" |
"http" | "details" | "/.*/api" |
"http" | "*" | "" |
"http" | "*" | "/.*/api" |
在 IntentFilter.java里的matchdata方法里可以看到其匹配处理过程,就是按照数组集合分别匹配的
public final int matchData(String type, String scheme, Uri data) {
final ArrayList<String> types = mDataTypes;
final ArrayList<String> schemes = mDataSchemes;
int match = MATCH_CATEGORY_EMPTY;
if (types == null && schemes == null) {
return ((type == null && data == null)
? (MATCH_CATEGORY_EMPTY+MATCH_ADJUSTMENT_NORMAL) : NO_MATCH_DATA);
}
if (schemes != null) {
if (<span style="background-color: rgb(255, 153, 255);">schemes</span>.contains(scheme != null ? scheme : "")) {
match = MATCH_CATEGORY_SCHEME;
} else {
return NO_MATCH_DATA;
}
final ArrayList<PatternMatcher> schemeSpecificParts = mDataSchemeSpecificParts;
if (schemeSpecificParts != null) {
match = hasDataSchemeSpecificPart(data.getSchemeSpecificPart())
? MATCH_CATEGORY_SCHEME_SPECIFIC_PART : NO_MATCH_DATA;
}
if (match != MATCH_CATEGORY_SCHEME_SPECIFIC_PART) {
// If there isn't any matching ssp, we need to match an authority.
final ArrayList<AuthorityEntry> authorities = mDataAuthorities;
if (authorities != null) {
int authMatch = <span style="background-color: rgb(255, 153, 255);">matchDataAuthority</span>(data);
if (authMatch >= 0) {
final ArrayList<PatternMatcher> paths = mDataPaths;
if (paths == null) {
match = authMatch;
} else if (<span style="background-color: rgb(255, 153, 255);">hasDataPath</span>(data.getPath())) {
match = MATCH_CATEGORY_PATH;
} else {
return NO_MATCH_DATA;
}
} else {
return NO_MATCH_DATA;
}
}
}
// If neither an ssp nor an authority matched, we're done.
if (match == NO_MATCH_DATA) {
return NO_MATCH_DATA;
}
} else {
// Special case: match either an Intent with no data URI,
// or with a scheme: URI. This is to give a convenience for
// the common case where you want to deal with data in a
// content provider, which is done by type, and we don't want
// to force everyone to say they handle content: or file: URIs.
if (scheme != null && !"".equals(scheme)
&& !"content".equals(scheme)
&& !"file".equals(scheme)) {
return NO_MATCH_DATA;
}
}
if (types != null) {
if (findMimeType(type)) {
match = MATCH_CATEGORY_TYPE;
} else {
return NO_MATCH_TYPE;
}
} else {
// If no MIME types are specified, then we will only match against
// an Intent that does not have a MIME type.
if (type != null) {
return NO_MATCH_TYPE;
}
}
return match + MATCH_ADJUSTMENT_NORMAL;
}
在data里设置了host或者port,mDataAuthorities就会进行记录