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

图片

阅读 433

活到老,学到老。

1 声望
1 粉丝
0 条评论
你知道吗?

活到老,学到老。

1 声望
1 粉丝
宣传栏