引入
一个新的版本发出,抽空复习一下开发基础。温故而知新~↖(^ω^)↗
今天的主题是 Android的启动模式。
我们从常用的Activity的启动开始展开。对于Acitivity的启动大家一定如数家珍。常用方式如下
Intent intent = new Intent(SplashActivity.this, HomeActivity.class);
startActivity(intent);
这种跳转我们称之为显式启动Activity。
今天我们关注的是另一种通过匹配启动Activity的方式,称之为隐式启动。先上一段隐式启动的代码。
Intent intent = new Intent("android.intent.action.demo");
intent.addCategory("com.husor.cate1");
intent.setDataAndType(Uri.parse("file://baidu.com"), "text/plain");
startActivity(intent);
这段代码,虽然没有直接指定是跳转哪个activity,但是却可以跳转到一个叫FilterDemo.class的页面。为何呢?
涉及到的关键是IntentFilter的隐式跳转匹配。
IntentFilter介绍
上方代码可以跳转到指定的activity,主要因为AndroidManifest中SplashAcitivity对应的声明:我们来看AndroidManifest文件。
<activity
android:name=".activity.FilterDemo"
android:label="@string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="@style/Theme.Beibei.Splash">
<intent-filter>
<action android:name="android.intent.action.demo" />
<category
android:name="com.husor.cate1"
android:name="com.husor.cate2"
android:name="android.intent.category.DEFAULT" />
<data android:mimeType = "text/plain"/>
<data android:scheme = "file"/>
</intent-filter>
</activity>
从intent-filter标签中可以看出,过滤分为3类: action, category, data.
我们一个一个来看,他是怎么过滤出我们所要跳转的activity是他的。
action的匹配规则
看AndroidManifest中声明的action
<action android:name="android.intent.action.demo" />
从代码中可以看出action对应的是一个字符串。Intent中的字符串与AndroidManifest中的字符串完全匹配(区分大小写,大小写不同会匹配失败,
如生成Intentnew Intent("android.intent.action.demo")
)就可以匹配到这个action.
注意:
1. new Intent的时候,你能为Intent定义一个唯一的action。
2. intent-filter中可以声明多个action。
3. 若Intent的action和intent-filter中的声明的action有一个匹配,就算匹配通过了
action已经匹配了, 我们来看category匹配。
category的匹配原则
类似与action,你可以定义很多个category如:
<category
android:name="com.husor.cate1"
android:name="com.husor.cate2"
android:name="android.intent.category.DEFAULT" />
系统默认添加的:
android:name="android.intent.category.DEFAULT"
我自己添加的:
android:name="com.husor.cate1"
android:name="com.husor.cate2"
匹配原则:
1:如果Intent中有设置category。那么Intent中设置的category,必须是AndroidManifest中声明的category的子集。如:
能匹配:
intent.addCategory("com.husor.cate2");
能匹配:
intent.addCategory("com.husor.cate1");
intent.addCategory("com.husor.cate2");
不能匹配:
intent.addCategory("com.husor.cate2");
intent.addCategory("com.husor.cate3");
2:可以不设置intent的Category.不设置会默认匹配成功,因为启动Intent的时候,系统会自动为你添加以下代码
intent.addCategory("android.intent.category.DEFAULT");
这就是为什么IntentFilter中会默认添加如下声明了。反过来说不添加这个声明,隐式跳转是无法生效的。
android:name="android.intent.category.DEFAULT"
data匹配原则
首先介绍data中的所有参数
<data android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:mimeType="string"
/>
前面六个参数很明显示是一个Uri结构的数据。(URI)结构不清楚的,自己去学习一下这里不做过多介绍。
最后一个参数是Type,指定了媒体类型。
匹配原则:
1:这里直接给实例
如:上面IntentFilter中涉及到了如下声明
<data android:mimeType = "text/plain"/>
<data android:scheme = "file"/>
为了匹配你需要为Intent设置如下代码即可跳转:
intent.setDataAndType(Uri.parse("file://baidu.com"), "text/plain");
2:注意要是用intent.setDataAndType来同时设置Uri信息和Type信息。使用intent.setData()或者Intent.setType()会相互制空。看源码就明白。
public Intent setData(Uri data) {
mData = data;
mType = null;
return this;
}
public Intent setType(String type) {
mData = null;
mType = type;
return this;
}
好了。这就是android基本的隐式跳转原则。有些默认值啥的细节,看官可以自己看看源码研究一下。我有空会再介绍一下相关细节。