Android中Activity的隐式启动
Posted 小二玩编程
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android中Activity的隐式启动相关的知识,希望对你有一定的参考价值。
ps:本文系转载文章,阅读原文可获取源码,文章末尾有原文链接
在android开发中,Activity的启动方式有2种,有两种是显示启动和隐式启动,显示启动是要指定被组件对象的信息(包名和类名);隐式启动就是在AndroidManifest.xml文件中的Activity IntentFilter;如果一个Activity的文章启动显示显示启动,又隐式启动,那么就以启动的方式启动;本该是讲信息IntentFilter,IntentFilter需要过滤,它需要过滤的信息有action、category、data,在调用的过程中,如果Intent不能匹配目标Activity的IntentFilter,那么启动Activity就会失败。
一个Activity的IntentFilter有多个,一个Intent任意匹配一个IntentFilter就可以成功启动Activity;只有一个Intent中匹配任意一个IntentFilter的action(至少一个)、category(至少一个)、data(至少一个)同时匹配成功启动Activity。
下面我放一下我自己写的简单IntentFilter的配置信息:
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="homePage"
android:scheme="recyclemobilephones" />
<data android:mimeType="video/*"/>
</intent-filter>
</activity>
1、动作的匹配原则
action的值是字符串,系统预定义了一些动作,我们也可以在自己的APP中自定义动作,一个IntentFilter可以有多个动作,Intent中动作值和IntentFilter任意一个动作值一样,包括必须字母大小写,只能算它们之间的动作匹配成功。
2、类别的匹配原则
category的是字符串类型,系统里值定义了几个类别,我们也可以自定义几个类别;一个Intent可以有多个类别,也可以没有,如果Intent有多个类别,那么Intent至少有一个类别和IntentFilter的类别相同,才能匹配成功;如果Intent里一个也没有类别,那么IntentFilter里必须配置
<category android:name="android.intent.category.DEFAULT" />
,不然的话匹配失败,因为在Activity的startActivity方法的实现
里默认给 category 添加 android.intent.category.DEFAULT 的。
3、数据的匹配原则
数据是由几个不同的属性组成的,并且它们的属性的值都是字符串类型的,如果 IntentFilter 中定义了数据,那么 Intent 中要添加切换相匹配的数据;下面是状态数据的属性属性哪些:
<data android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:mimeType="string"
>
</data>
我们来分析一下数据,总体上来说数据是由mimeType和Uri组成,mimeType是指图像/jpeg、video/*等各种媒体格式,Uri的数据格式比较复杂,还有Uri的组成:
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
方案:模式,是http等,假方案一般没有在Uri中,那么Uri的其他参数是束缚的。
主持人:主机名,比如 www.xxx.com,xxx 一般是公司的名字,如果主机没有定义,那么就和方案一样,Uri 的其他参数也是优秀的。
端口:端口号,比如8080。
path:完整的路径信息。
pathPattern:完整的路径信息,它里面还可以包含通配符 * 。
pathPrefix:路径的定位信息。
需要注意的是,如果 Intent 要使用完整的数据,也就是 Uri 和 mimeType,可以调用 Intent 的 setDataAndType 方法,不能把 Intent 的 setType 和 setData 方法一起调用,它们两种方法都是把对方的值彼此置入空的,要两个方法 Uri 和 mime Type 一个必须是空的,下面看看这两个的源码。
Intent 的 setType 方法:
public @NonNull Intent setType(@Nullable String type) {
mData = null;
mType = type;
return this;
}
Intent 的 setData 方法:
public @NonNull Intent setData(@Nullable Uri data) {
mData = data;
mType = null;
return this;
}
好,下面我们列举一个用隐式启动活动的例子,每个例子的IntentFilter都必须添加一行代码,如下所示:
<category android:name="android.intent.category.DEFAULT" />
(1)利用系统预定义的action启动Activity:
执行startActivity方法的Intent的代码如下
var intent: Intent = Intent(Intent.ACTION_VIEW);
intent.putExtra("key","这是利用系统预定义的action启动Activity")
startActivity(intent)
AndroidManifest.xml 文件中 Activity 的 IntentFilter 配置如下
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
(2)利用自定义的action启动Activity:
执行startActivity方法的Intent的代码如下
var intent: Intent = Intent("xiaoer");
intent.putExtra("key","这是利用自定义的action启动Activity")
startActivity(intent)
AndroidManifest.xml 文件中 Activity 的 IntentFilter 配置如下
<intent-filter>
<action android:name="xiaoer" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
(3)利用系统预定义的category启动Activity,action用android.intent.action.VIEW:
执行startActivity方法的Intent的代码如下
var intent: Intent = Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_APP_BROWSER)
intent.putExtra("key","这是利用系统预定义的category启动Activity")
startActivity(intent)
AndroidManifest.xml 文件中 Activity 的 IntentFilter 配置如下
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.APP_BROWSER"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
(4)利用自定义的category启动Activity,action用android.intent.action.VIEW:
执行startActivity方法的Intent的代码如下
var intent: Intent = Intent(Intent.ACTION_VIEW);
intent.addCategory("xiaoer_study")
intent.putExtra("key","这是利用自定义的category启动Activity")
startActivity(intent)
AndroidManifest.xml 文件中 Activity 的 IntentFilter 配置如下
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="xiaoer_study" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
(5)利用只包含uri的data启动Activity,action用android.intent.action.VIEW:
执行startActivity方法的Intent的代码如下
var intent: Intent = Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("recyclemobilephones://homePage"))
intent.putExtra("key","这是利用只含有uri的data启动Activity")
startActivity(intent)
AndroidManifest.xml 文件中 Activity 的 IntentFilter 配置如下
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="homePage"
android:scheme="recyclemobilephones" />
</intent-filter>
(6)利用带有uri和mimeType的data启动Activity,action用android.intent.action.VIEW:
执行startActivity方法的Intent的代码如下
var intent: Intent = Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("recyclemobilephones://homePage_2"),"text/plain")
intent.putExtra("key","这是利用含有uri和mimeType的data启动Activity")
startActivity(intent)
AndroidManifest.xml 文件中 Activity 的 IntentFilter 配置如下
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="homePage_2"
android:mimeType="text/plain"
android:scheme="recyclemobilephones" />
</intent-filter>
APP运行后的界面如下所示:
图片
点击任意一个请按钮,如果弹出选择框,点击“IntentFilter”APP
图片
以上是关于Android中Activity的隐式启动的主要内容,如果未能解决你的问题,请参考以下文章