我是靠谱客的博主 务实嚓茶,最近开发中收集的这篇文章主要介绍Android IntentFilter匹配规则显式调用隐式调用,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

显式调用

Intent intent = new Intent();
intent.setClassName(“lbb.demo.anotest”, “lbb.demo.anotest.TwoActivity”);
startActivity(intent);
打开包名为”lbb.demo.anotest”的 “lbb.demo.anotest.TwoActivity”方法。。。可能启动另外一个app

new Intent(this,AnoActivity.class); 打开当前应用的AnoActivity

隐式调用

Action,Catogory匹配

//此时action为”lbb.demo.anotest.TwoActivity”,同时默认添加DEFAULT的category
Intent intent = new Intent(“lbb.demo.anotest.TwoActivity”);
//intent.addCategory(“android.intent.category.DEFAULT”);
startActivity(intent);
//此时根据AMS规则,是全局查找的。。。并不是只针对于当前应用。。可能启动另外一个app


<activity
android:name=".TwoActivity"
android:label="@string/title_activity_two"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="lbb.demo.anotest.TwoActivity"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>

category android:name=”android.intent.category.DEFAULT”这样是必不可少的。否则隐式匹配不到该activity,同时注意大小写匹配

Data匹配

Each element can specify a URI and a data type (MIME media type). There are separate attributes —scheme, host, port, and path — for each part of the URI:
scheme://host:port/path or pathPrefix or pathPattern
For example, in the following URI,
content://com.example.project:200/folder/subfolder/etc
the scheme is “content”, the host is “com.example.project”, the port is “200”, and the path is “folder/subfolder/etc”.

path 用来匹配完整的路径,如:http://example.com/blog/abc.html,这里将 path 设置为 /blog/abc.html 才能够进行匹配;
pathPrefix 用来匹配路径的开头部分,拿上来的 Uri 来说,这里将 pathPrefix 设置为 /blog 就能进行匹配了;
pathPattern 用表达式来匹配整个路径,这里需要说下匹配符号与转义。

匹配符号:
” 用来匹配0次或更多,如:“a” 可以匹配“a”、“aa”、“aaa”…
“.” 用来匹配任意字符,如:“.” 可以匹配“a”、“b”,“c”…
因此 “.*” 就是用来匹配任意字符0次或更多,如:“.*html” 可以匹配 “abchtml”、“chtml”,“html”,“sdf.html”…

转义:因为当读取 Xml 的时候,“/” 是被当作转义字符的(当它被用作 pathPattern 转义之前),因此这里需要两次转义,读取 Xml 是一次,在 pathPattern 中使用又是一次。如:“” 这个字符就应该写成 “//”,“/” 这个字符就应该写成 “”。

setType 调用后设置 mimeType,然后将 data 置为 null;
setData 调用后设置 data,然后将 mimeType 置为 null;
setDataAndType 调用后才会同时设置 data 与 mimeType。
setDataAndType不等同于先调用setData后调用setType,尤其注意

URI的schema是有默认值的,默认值是”content”/”file”

<intent-filter>
<data android:mimeType="video/mpeg"/>
</intent-filter>
//正确方式
intent.setDataAndType(Uri.parse("file://abc"), "video/mpeg");
intent.setDataAndType(Uri.parse("content://abc"), "video/mpeg");
intent.setType("video/mpeg");

intent.setDataAndType(Uri.parse(“http://abc“), “video/mpeg”);
这样是匹配不到的,因为schema部分不匹配默认值是”content”/”file”

PackageManager相关方法

如果有多个action匹配就会出现选择框。。如果没有任何一个,就会Force Close,所以可以通过方法检查是否有符合条件的activity,避免FC
PackageManager方法


/**
* Determine the best action to perform for a given Intent.
This is how
* {@link Intent#resolveActivity} finds an activity if a class has not
* been explicitly specified.
*
* <p><em>Note:</em> if using an implicit Intent (without an explicit ComponentName
* specified), be sure to consider whether to set the {@link #MATCH_DEFAULT_ONLY}
* only flag.
You need to do so to resolve the activity in the same way
* that {@link android.content.Context#startActivity(Intent)} and
* {@link android.content.Intent#resolveActivity(PackageManager)
* Intent.resolveActivity(PackageManager)} do.</p>
*
* @param intent An intent containing all of the desired specification
*
(action, data, type, category, and/or component).
* @param flags Additional option flags.
The most important is
* {@link #MATCH_DEFAULT_ONLY}, to limit the resolution to only
* those activities that support the {@link android.content.Intent#CATEGORY_DEFAULT}.
*
* @return Returns a ResolveInfo containing the final activity intent that
*
was determined to be the best action.
Returns null if no
*
matching activity was found. If multiple matching activities are
*
found and there is no default set, returns a ResolveInfo
*
containing something else, such as the activity resolver.
*
* @see #MATCH_DEFAULT_ONLY
* @see #GET_INTENT_FILTERS
* @see #GET_RESOLVED_FILTER
*/
public abstract ResolveInfo resolveActivity(Intent intent, int flags);
/**
* Retrieve all activities that can be performed for the given intent.
*
* @param intent The desired intent as per resolveActivity().
* @param flags Additional option flags.
The most important is
* {@link #MATCH_DEFAULT_ONLY}, to limit the resolution to only
* those activities that support the {@link android.content.Intent#CATEGORY_DEFAULT}.
*
* @return A List&lt;ResolveInfo&gt; containing one entry for each matching
*
Activity. These are ordered from best to worst match -- that
*
is, the first item in the list is what is returned by
*
{@link #resolveActivity}.
If there are no matching activities, an empty
*
list is returned.
*
* @see #MATCH_DEFAULT_ONLY
* @see #GET_INTENT_FILTERS
* @see #GET_RESOLVED_FILTER
*/
public abstract List<ResolveInfo> queryIntentActivities(Intent intent,
int flags);

看两个方法的注释

resolveActivity返回最佳匹配,找不到匹配的返回null
queryIntentActivities 返回所有的,找不到匹配的返回null
flags必须是CATEGORY_DEFAULT,增加catogory匹配规则,否则会忽略category匹配,那么可能会导致startactivity/startservice失败

最后实现肯定是通过PMS(PackageManagerService)执行对应方法,IBinder通信

综合前面,AMS,WMS,PMS都介绍过了。

例子


<activity

android:name=".TestActivity"
android:label="@string/title_activity_test"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.TestActivity"/>
<category android:name="android.intent.category.DEFAULT"/>
<data

android:host="baidu"
android:mimeType="image/png"
android:scheme="http"/>
</intent-filter>
</activity>

@OnClick(R.id.but)
void OnClick() {
Intent intent = new Intent();
intent.setAction("android.intent.action.TestActivity");
intent.setDataAndType(Uri.parse("http://baidu:8888/abc/..."), "image/png");
PackageManager pm = getPackageManager();
if (pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
startActivity(intent);
}else{
Log.d("LiaBin","no match intent");
}
}

最后

以上就是务实嚓茶为你收集整理的Android IntentFilter匹配规则显式调用隐式调用的全部内容,希望文章能够帮你解决Android IntentFilter匹配规则显式调用隐式调用所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部