Android 学习笔记 [1]:显式 Intent 和隐式 Intent 的区别

hjthjthjt 4月 27, 2018

非常作死的新开坑,虽然实际目的是给自己做笔记方便查阅23333

Intent,翻译为意图也差不多,实际上就是一个用来启动自身或者自身以外的 Activity 的东西。

在官方文档中,Intent 大概是这样的:

java.lang.Object
   ↳    android.content.Intent
Intent(Context packageContext, Class<?> cls);

Context 是 Android 中非常常见的东西,很抽象但是又必不可少,通常我们称为 上下文,在这里它充当一种类似于编程时创建变量(int i;中的int)。
因此 Context packageContext 实际上是让你放入此时的上下文。

比方说,你使用 Intent 的地方是 MainActivity.class,那么这里的 Context packageContext 可以……

Intent intent = new Intent(this,......); //此处的 this
//或者
Intent intent = new Intent(this.getPackageName(),......); //此处的 this.getPackageName()
//或者
Intent intent = new Intent(MainActivity.this,......); //此处的 MainActivity.this

可以看到并不是只有一种方式来引入上下文¯\_(ツ)_/¯

显式 Intent

首先说清楚显式 Intent 是什么。
显式 Intent,顾名思义,直接暴露出你所要启动的 Activity。

比方说,我们这里要通过点击按钮,打开你写的应用中的 MohaActivity.class,那么此时你在代码中就要写出来 MohaActivity.class

上代码:

//这里我就只用上面那个 this 做示范
Intent intent = new Intent(this,"MohaActivity.class");

这样的话,点击按钮后程序便会启动 MohaActivity 这个 Activity

为什么是 "MohaActivity.class"呢?我们回到上面,可以看到文档中括号后半部分是 Class<?> cls,与前面 Context 一样,应该可以推断出这里要放的是 Class,因此我们写的是 .class

同样,引入 Class 也不止一种:

//假设你应用的包名是 com.haha.baoli
Intent intent = new Intent(this,"com.haha.baoli.MohaActivity");

上面这种是直接把 ComponentInfo 搬上去。

ComponentInfo是什么?
ComponentInfo,拆词翻译的话就是“组件信息”。其实非常好理解,com.haha.baoli.MainActivity,com.haha.baoli.MohaActivity 这些均是 ComponentInfo。简单的解释就是“包名.Class名”,你也许不知道它到底是个什么鬼东西,但是知道怎么用应该不难。

大概想一想可以知道,我们可以用相同的办法打开其他非自身的 Activity,譬如:

//打开 QQ 主界面的话……
Intent intent = new Intent(this,"com.tencent.mqq.SplashActivity");
//打开 微信 主界面的话……
Intent intent = new Intent(this,"com.tencent.mm.MainActivity");

QQ 和 微信 的主界面的 Activity 名分别为 SplashActivityMainActivity

实际上,显式 Intent 的使用非常简单,例如上面对 intent 实例化后只需要这样就可以启动 Activity 了:

startActivity(intent);

隐式 Intent

与显式 Intent 相对的就是隐式 Intent。
两者在用法上有区别,但实际实现到用户层是没区别的。

在隐式 Intent 中,我们不需要写出具体的 Activity。

那么它到底是什么呢?举个例子:
你日常生活中用到的 分享功能 在大部分情况下就是使用隐式 Intent 的。

比方说,你现在截图了屏幕,当你从通知栏中选择分享的话,基本会遇到 Android 展开一个选择列表,其中的应用均是相册应用或其中具有相册功能的应用或常见的中国流氓软件啥鸡儿东西都要申请一波导致系统打开啥都有它
同样,如果你打开了一个 zip 文件,系统会询问你要用哪个支持查看 zip 的软件打开。

实际上,你打开这个文件的过程就是发出了隐式 Intent,由系统来判断用哪个应用打开,而系统判断你的依据是默认应用或此时选中的应用_(:з」∠)_

简单的说,就是显式 Intent 要求在代码中写出确切的类,而隐式 Intent 则由系统去判断用谁打开。

隐式 Intent 又要怎么用呢?
主要是依靠 intent-filter 中的内容来筛选。
例如下面一段 XML,提取自 AndroidManifest.xml

<activity
    android:name="com.haha.baoli.MohaActivity">
    <intent-filter>
        <action android:name="naive"/>
        <category android:name="tooyoung_toosimple"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

可以看到, intent-filter 中有 action(动作) 和 category(类别) 和 data(数据)←直译中文别打我
一般启动隐式 Intent 便通过这三个东西来筛选。

action 筛选

看看下面这段代码,它通过 naive 筛选出我们上面定义的 com.haha.baoli.MohaActivity。而使用 naive 可以不止一个,这也因此可供用户选择究竟由谁来打开内容。
再骂一句国产软件瞎鸡儿申请跟它毛关系都没有的action

Intent intent = new Intent();
intent.setAction("naive");
startActivity(intent);
//执行此代码后,程序将会要求系统列出 action 为 naive 的所有应用,或直接打开已设置的默认程序。

很多情况下,开发者只会对例如打开图片等系统操作使用如此简单的 action 命名,但是如果你开发的软件在唤起另一个特有软件的时候,你就不应该这么简单命名了,正确的方式应该是 包名+action name,例如 com.haha.baoli.naive。或者是调用系统,例如 android.intent.action.SEND。

注意:用户的设备中,可能没有任何应用,用于处理您发送的隐式 Intent。如果出现这种情况,则调用将会失败,且应用会崩溃。要验证 Activity 是否会接收 Intent,请对 Intent 对象调用 resolveActivity()。如果结果为非空,则至少有一个应用能够处理该 Intent,且可以安全调用 startActivity()。 如果结果为空,则不应使用该 Intent。——来自 Android Developer Guide

category 筛选

与上面类似:

Intent intent = new Intent();
intent.setAction("naive");
intent.addCategory("tooyoung_toosimple");
startActivity(intent);

如果没有使用 addCategory() 来添加一个 category,则程序默认的 category 为 android.intent.category.DEFAULT

data 筛选

常见的 data 写法,当然,不是全都要写:

<data android:scheme="too"
    android:host="young"
    android:port="too"
    android:path="simple"
    android:pathPattern="sometimes"
    android:pathPrefix="naive"
    android:mimeType="angry" />

与上面类似:

Intent intent = new Intent();
intent.setAction("naive");
intent.addCategory("tooyoung_toosimple");
Uri uri = Uri.parse("content://com.haha.baoli/IamAngryWhenAHongKongReporterAskMeSomethingIdonotLike.mp4");
intent.setDataAndType(uri, "video/mp4");
startActivity(intent);

当使用 android:port 及其之下的标签时,Java 代码中要做相应的匹配。

总结(?)

来自一个渣渣的完全没有正确性保证的瞎写文章,大量错误请大佬们评论指出_(:з」∠)_

本文采用 CC BY-NC-SA 3.0 协议进行许可,在您遵循此协议的情况下,可以自由共享与演绎本文章。
本文链接:https://jakting.com/archives/android-learn-1.html

  1. 说道:

    这是什么评论啊?valine吗

    1. hjthjthjt说道:

      WordPress自带评论框……

      1. 说道:

        哦哦,很棒很棒,valine开个邮件提醒好麻烦

        1. hjthjthjt说道:

          所以我直接魔改WordPress评论框23333

发表评论

电子邮件地址不会被公开。 必填项已用*标注