1)Aciton只要能匹配到其中一个字符串就可以
2)category 假如Activity如下声明
<activity android:name=".ActivitySecond">
<intent-filter>
<action android:name="second"></action>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="a"></category>
<category android:name="b"></category>
<category android:name="c"></category>
<category android:name="d"></category>
</intent-filter>
</activity>
我把这些category看成一个集合{a,b,c,d},只要是Intent的category是它的子集{a,c}{c,d}那么就可以成功启动
Intent intent = new Intent();
intent.setAction("second");
intent.addCategory("a");
startActivity(intent);
但是形如下面的不可以
Intent intent = new Intent();
intent.setAction("second");
intent.addCategory("a");
intent.addCategory("e");
startActivity(intent);
但是我如果把
<category android:name="android.intent.category.DEFAULT"/>
去掉之后,是不能成功启动的,我去查了一些也没弄明白为啥?
只好去看源码,根据的Activity的启动过程开始了我的分析,下面是执行流程
1、 Activity.java
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options)
2、Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options)
3、ActivityManagerService.java
final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container)
4、ActivityStarter.java
final int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
Bundle bOptions, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask)
注意这里有一句话
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
5、ActivityStackSupervisor.java
ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {
try {
return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,
PackageManager.MATCH_DEFAULT_ONLY | flags
| ActivityManagerService.STOCK_PM_FLAGS, userId);
} catch (RemoteException e) {
}
return null;
}
给这个flags 添加了一个
PackageManager.MATCH_DEFAULT_ONLY
然后调用了另一个方法
6、PackageManagerService.java
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
这个方法里有个调用,这个方法意思大概是查询符合条件所有的activity信息,存到一个list中,后面都是在查询返回这个list
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
flags, userId);
7、还是这个类PackageManagerService.java
private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, int userId)
在这个方法中有这个方法
List<ResolveInfo> result = mActivities.queryIntent(
intent, resolvedType, flags, userId);
8、这是个内部类,mActivities 是这个内部类的一个实例
final class ActivityIntentResolver
extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo>
方法调用如下
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
int userId) {
if (!sUserManager.exists(userId)) return null;
mFlags = flags;
return super.queryIntent(intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
}
根据刚才的flag (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0 这个值应该是个true == defaultOnly
又调用了父类的这个方法
9、IntentResolver.java
父类方法如下
public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly,
int userId)
其中
buildResolveList(intent, categories, debug, defaultOnly,
resolvedType, scheme, firstTypeCut, finalList, userId);
在这个方法里
if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) {
final R oneResult = newResult(filter, match, userId);
if (oneResult != null) {
dest.add(oneResult);
if (debug) {
dumpFilter(logPrintWriter, " ", filter);
logPrintWriter.flush();
filter.dump(logPrinter, " ");
}
}
} else {
hasNonDefaults = true;
}
只有当filter中有Intent.CATEGORY_DEFAULT或者当defaultOnly == false,才会结果添加到list,因为这里defaultOnly已经是true了,如果没有这filiter中添加Intent.CATEGORY_DEFAULT不会添加到list中,因此在Mainfest中必须要添加。
<category android:name="android.intent.category.DEFAULT"/>
为什么要有这种机制,filter.hasCategory(Intent.CATEGORY_DEFAULT),返回值有很多false,是LAUNCH的启动的。
3)data
<data android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:mimeType="sting"
/>
Uri的格式:scheme://host:port/path or pathPrefix or pathPattern
跟action类似 对应着下面的这个URI。
含义 scheme: 模式 http、file、content
host: 主机名
path:路径,pathPrefix 正则表达式 ,pathPattern含有通配符“*”的路径
intent.setDataAndType
对应写上就可以了.