显式Intent与隐式Intent

1、显式Intent(explicit intent)

显式Intent明确指定了要启动的activity:

  Intent intent= new Intent(this, Target.class)

2、隐式Intent(implicit intent)

隐式Intent没有明确指定要启动的activity ,而是通过设置一些Intent Filter来让系统去筛选合适的activity来启动。Intent到底发给哪个activity,需要进行三个匹配,一个是action,一个是category,一个是data:
在startActivity()时,android会默认加上一个CATEGORY_DEFAULT,这样一来如果intent filter中没有android.intent.category.DEFAULT这个category的话,匹配就会失败,你的程序一定会崩溃!所以,如果你的activity支持接收隐式Intent的话就一定要在intent filter中加入以下这个category:

<category android:name="android.intent.category.DEFAULT"/>

如果组件不声明intent-filter,那么所有的隐式Intent事件都不会发送给该组件。

3、data由URI来描述和定位,URI由三部分组成,

scheme://host:port/path      模式://主机:端口/路径
<data android:mimeType=""
android:scheme=""
android:host=""
android:port=""
android:path=""
android:pathPrefix=""
android:pathPattern=""/>

上面<data…/>元素支持如下属性:

mimeType:用于声明该组件所能匹配的Intent的Type属性。
scheme:用于声明该组件所能匹配的Intent的Data属性的scheme部分。
host:用于声明该组件所能匹配的Intent的Data属性的host部分。
port:用于声明该组件所能匹配的Intent的Data属性的port部分。
path:用于声明该组件所能匹配的Intentde Data属性的path部分。
pathPrefix:用于声明该组件所能匹配的Intent的Data属性的path前缀。
pathPattern:用于声明该组件所能匹配的Intent的的Data属性的path字符串模板。
Intent的Type属性也用于指定该Intent的要求,必须对应组件中<intent-filter…/>元素中<data…/>子元素的mineType属性与此相同,才能启动该组件。

例子:

如果我们的manifest.xml是这样的:

<manifest>
...
    <application>
    ...
        <activity
            android:name=".LoginActivity"
            android:label="@string/title_activity_login">
            <intent-filter>
                <action android:name="com.wong.mytesta.W" />
                <category android:name="android.intent.category.DEFAULT" />
                <data
                    android:host="com.wong.www"
                    android:mimeType="text/haha"
                    android:path="/mytest"
                    android:port="1000"
                    android:scheme="wong"/>
            </intent-filter>
        </activity>
        <activity
            android:name=".NavigationActivity"
            android:label="@string/title_activity_navigation"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="com.wong.mytesta.WWW" />
                <category android:name="com.wong.MyCategory" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".TabActivity"
            android:label="@string/title_activity_tab"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="com.wong.mytesta.WWW" />
                <category android:name="com.wong.MyCategory" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".SettingsActivity"
            android:label="@string/title_activity_settings">
            <intent-filter>
                <action android:name="com.wong.mytesta.WWWB" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        ...
    </application>

</manifest>

我们用隐式来启动SettingsActivity:

Intent intent = new Intent();
intent.setAction("com.wong.mytesta.WWWB");
startActivity(intent);

如果我们用com.wong.mytesta.WWW启动activity,就会弹出两个activity让我们选择,因为根据intent filter的匹配规则,有两个activity符合,即TabActivity和NavigationActivity:

Intent intent = new Intent();
intent.setAction("com.wong.mytesta.WWW");
startActivity(intent);

使用data来启动activity:

Intent intent = new Intent();
intent.setDataAndType(Uri.parse("wong://com.wong.www:1000/mytest"),"text/haha");
startActivity(intent);

例外情况:

<intent-filter>
 	<action android:name="android.intent.action.MAIN" />
	<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

以上的intent filter中没有必要加入android.intent.category.DEFAULT,当然加入也没有问题。

参考代码


版权声明:本文为weixin_40763897原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。