转载请注明出处:http://blog.youkuaiyun.com/a992036795/article/details/51538083
我们知道,启动Activity分为两种,显示调用和隐式调用。显示调用需要明确的指定被启动对象的组件信息,包括包名和类名,而隐式调用则不需要明确的指定组件信息。原则上一个Intent不应该即是显示调用又是隐式调用。如果二者共存的话以显示调用为主。
隐式调用需要Intent能够匹配目标组组件的IntentFilter中所设置的过滤信息,如果不匹配将无法启动目标的Activity。
IntentFilter中的过滤信息有action、category、data。
一个Activity中可以有多个Intent-Fileter,一个intent只要能匹配任何一组intent-filter即可成功启动对应的Activity。
一个Intent-Filter中的action、category、data可以有多个。只有一个Intent同时匹配action、category、data类别才算是完全匹配。BroadcastReceiver只需匹配action或data就可以启动。
那么怎么样才来匹配action、category、data呢?
1、action: intent指定的action,只要和intent-filter中指定的多个action中的一个action相同(区分大小写) 相同,就算匹配成功。
2、category:intent中指定的所有 category、必须在intent-filter中存在,才算匹配成功。(这里注意intent默认添加有category :android.intent.category.LAUNCHER,所有在activity的intent-filter中需添加android.intent.category.LAUNCHER。才能完成匹配。)
3、data:data和action类似,只要指定的data和intent-filter中的任意一个data匹配,就算匹配成功。(注意:如果在intent中没有指明scheme,默认为content和file。一个完整的URI必须要有 scheme和host)
最后,为了避免使用隐式启动方法找不到符合的activity而报错可以使用如下方法进行检查:
PackageManager的方法:
//flags = #MATCH_DEFAULT_ONLY 使用这个标志可以找到category添加 //"android.intent.category.DEFAULT"的activity
//返回最佳的匹配activity
public abstract ResolveInfo resolveActivity(Intent intent, int flags);
或者:
//返回所有可以匹配的信息
public abstract List<ResolveInfo> queryIntentActivities(Intent intent,
int flags);
或者Intent中的方法:
//实质还是调用了packageMangager.resolveActivity()方法
public ComponentName resolveActivity(PackageManager pm) {
if (mComponent != null) {
return mComponent;
}
ResolveInfo info = pm.resolveActivity(
this, PackageManager.MATCH_DEFAULT_ONLY);
if (info != null) {
return new ComponentName(
info.activityInfo.applicationInfo.packageName,
info.activityInfo.name);
}
return null;
}
结尾在提醒一句,android5.0 之后service只接受显示启动。