显示方式就是在通过intent启动Activity时指定了Activity的包名和类名,而且不管启动本应用的Activity还是启动其他应用的Actitity
例如:要启动的Activity是同一个项目之中:
Intent intent = new Intent(context, MyActitity.class);
startService(intent);
如果因为也是在同一个项目之中,但特殊原因不能直接引用XXXActivity,也可以通过loadClass,传入完整的包名来启动Activity:
try {
Class c = context.getClassLoader().loadClass("com.xxx.MyActivity");
Intent intent = new Intent(context, c);
startActivity(context, intent);
} catch(ClassNotFoundException ex) {
ex.printStackTrace();
}
又例如:要启动的Activity不在同一个项目之中:
ComponentName cn = new ComponentName("packageName",com.xxx.MyActivity");
Intent intent = new Intent();
intent.setComponent(cn);
startActivity(intent);
或者:
Intent intent = new Intent("android.intent.action.MAIN");
intent.setClassName("packageName","com.xxx.MyActivity");
startActivity(intent);
隐式启动Activity需要同时匹配过滤列表中的action、cetegor、data信息。action、cetegor和data可以有多个,同一类别的信息共同约束当前类别的匹配过程。一个Activity中可以有多个intent-filter,一个Intent只要能匹配任何一组intent-filter即可成功启动对应用Activity。
下面是一个过滤规则的示例:
匹配实例代码:
Intent intent = new Intent("com.xxx.a");
intent.addCategory("com.xxx.c");
intent.setDataAndType(Uri.parse("file://abc"), "text/plain");
startActivity(intent);
action是一个字符串,系统预定义了一些action,同时我们也可以在应用中定义自己的action,action区分大小写。action的匹配规则是Intent中的action必须能够和过滤规则中的action字符串完全一样。一个过滤中可以有多个action,Intent中的action能够和过滤规则中的任何一个action相同即可匹配成功。
category是一个字符串,系统预定义了一些category,同时我们也可以在应用中定义自己的category。category要求Intent中如果含有category,不管有多少个,都必须和过滤规则中的其中有定义的category相同。当然,Intent中可以没有category,如果没有category的话,按照上面的描述,这个Intent仍然可以匹配成功。原因是系统在调用startActivity或者startActivityForResult的时候会默认为Intent加上”android.intent.category.DEFAULT”这个category,所以这个category就可以匹配前面的过滤规则中的第三个category。同时,为了我们的activity能够接收隐式调用,就必须在intent-filter中指定”android.intent.category.DEFAULT”这个category。即是说,在Intent中可以没有category,但有的情况下,哪怕是其中一个都不能无中生有。
data的匹配规则和action类似,如果过滤规则中定义了data,那么Intent中必须也要定义可匹配的data。data的语法如下所示:
data由两部分组成,mimeType和URI。mimeType指媒体类型,比如image/jpeg、audio/mpeg4-generic和video/*等,可以表示图片、文本、视频等不同的媒体格式,而URI中包含的数据就比较多了,下面是URI的结构:
://:/[||]
scheme: URI的模式,比如http、file、content等。如果URI中没有指定scheme,那么整个URI的其它参数无效,这也意味着URI是无效的。
host: URI的主机名,比如www.baidu.com,如果host未指定,那么整个URI中的其他参数无效,这也意味着URI是无效的。
port: URI中的端口号,比如80,仅当URI中指定了scheme和host参数的时候port参数才是有意义的。
path、pathPattern和pathPrefix: 这三个参数表述路径信息,其中path表示完整的路径信息;pathPattern也表示完整的路径信息,但是它里面可以包含通配符“*”,“*”表示0个或多个任意字符,需要注意的是,由于正则表达式的规范,如果想表示真实的字符串,那么“*”要写成“\\*”,”\”要写成”\\\\”;pathPrefix表示路径的前缀信息。
1、 如下过滤规则:
匹配实例:
intent.setDataAndType(Uri.parse("file://abc"),"image/png")
说明:
这种规则mimeType属性必须为“image/*”才能匹配,虽然过滤规则没有指定URI,但是却有默认值,URI的默认值为content和file。
2、 如下过滤规则:
匹配实列:
intent.setDataAndType(Uri.parse("http://abc"),"video/mpeg")
或者
intent.setDataAndType(Uri.parse("http://abc"),"audio/mpeg")
如下两种特殊写法,它们的作作是一样的:
…
和
…
当我们通过隐式方式启动一个Activity时,如果没有匹配Activity则会出现错误,所以我们在匹配前可以使用PackageManager的resolveActivity方法或者Intent的resolveActivity方法。如果它们找不到匹配的Activity则返回null。PackageManager还提供了queryIntentActivities方法,这个方法不是返回最佳匹配的Activity信息,而是返回所有成功匹配的Activity信息。
有时,可以在startActivity前,先判断Intent是否有效,可以这样:
private static boolean isIntentAvailable(Context context, Intent intent) {
if (intent == null) {
return false;
}
boolean isAvailable = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
return isAvailable;
}
以上代码,二者共同作用是用来标明这是一个入口Activity并且会出现在系统的应用列表中,少了任何一个都没有实际意义。
——本博文部分内容参考自《Android开发艺术探索》