Android中的意图机制

Android学习编程的基础是基础类。它们是整个源代码的框架——我们从中创建成熟应用程序的“砖块”。这些类别之一是意图。今天我们将了解它是什么以及如何使用它。

Intent意图

Intent 是一个描述特定动作的变量。在 Android 操作系统中,许多应用程序机制基于此参数工作。

大多数情况下,我们使用 Intent 在应用程序中启动另一个活动。但是,我们可以将该机制用于其他目的。例如,通知第三方 Activity 或其他执行特定操作的服务的启动。此外,Intent 用于通知特定事件。

换句话说,Intent 是一个指定应该触发哪个 Activity 的对象。它看起来像这样:

val intent: Intent = Intent(this, ActivityTwo::class.java)
startActivity(intent)

在指定应该触发哪个 Activity 之后,代码必须将此变量传递给 startActivity 方法。它会自动找到所需的活动并显示它。

Intent 是使用两个主要组件创建的。

首先,这是上下文。Activity 是 Context 变量的子类。我们可以以“this”的形式使用它。

上下文是一个源代码变量,可以访问应用程序的关键功能。其中包括对资源、文件等的访问。

由于这个参数,应用程序可以执行多个活动(Activity),这些活动可以通过仅访问类名来触发。

第二个组成部分是类名。必须在向清单添加 Activity 时指定。通过在 Intent 中指定此名称,代码算法将自动找到相似度并启动所需的 Activity。

很容易检查。您只需要从清单中删除 Activity 名称并尝试激活它。在这些操作之后,应用程序将开始生成错误警报。日志将指示这样的类不存在。此外,系统本身会告诉我们它没有写在清单中。如果您在清单中重写 Activity,则不会有任何错误。

显式调用

显式 Activity 调用是使用您在其中输入类名的 Intent 参数的调用。此方法用于在单个程序中工作。它看起来像这样:

我们在写入Activity-Class_B的参数中创建一个Intent变量。之后,我们使用添加的 Intent 启动 startActivity 方法。程序会自动在清单文件中找到一个带有 Class_B 参数的 Activity。如果这样的变量不存在,我们会看到一个错误。否则,一切正常。整个过程发生在一个程序中。

隐式调用

隐式调用不同于显式调用。在这种情况下,我们没有在 Intent 中指定类名。相反,我们使用参数 action、data 和 category。它们都有特定的含义。这些值加在一起,为代码创建了一个任务。

在 Activity 变量中,我们指定 IntentFilter 参数。它们还包括操作、数据和类别。这些变量的值由 Activity 的具体情况和任务决定。

如果这些参数与Intent一致,则程序开始工作(即调用Activity)。

与此处显式调用的区别在于,这种方法将在一个应用程序和整个操作系统中都有效。这意味着隐式调用会导致代码不仅在一个程序内部而且在整个设备文件中搜索 Activity。

为了说明隐式调用的操作原理,我们可以执行以下操作:

Intent 参数在第一个应用程序(应用程序 1)内创建。在那里,我们规定了动作、数据和类别的类别。然后,使用 startActivity,我们开始搜索所需的 Activity。

程序开始在系统的所有应用程序中搜索Activity——这在图中使用不同的应用程序(Application)来说明。

在系统内部,StartActivity 正在搜索具有必要参数的 Activity 的应用程序。这意味着它正在寻找一个执行 Intent 类别中指定的功能的变量。

可能有几个合适的活动(Activity)。如果其中有多个,则用户打开一个应用程序列表,他们可以从中选择所需的程序。

因此,显式调用和隐式调用之间的区别在于,在第二种情况下我们不使用类名——而是由其他三个参数来代替。它们的特殊性允许程序在单个应用程序的限制之外工作。

有意图的工作方法

使用 Intent 参数的主要方法有以下三种:

  • getCategories – 根据函数参数中设置的标准接收所有类别;
  • removeCategory – 删除类别;
  • addCategory – 向 Intent 添加一个类别。

我们使用它们来处理代码中的类别。

意图过滤器

我们需要 Intent 过滤器,以便系统可以从可能的应用程序列表中自动选择一个应用程序来执行所需的功能。过滤器选择可用于特定数据类型的活动列表和其他参数。

我们可以通过将 <intent-filter> 标签添加到清单中来创建一个充当 Intent 过滤器的代码元素。

过滤器指定 Intent–action、数据和类别组件。其他元素不影响过滤器的运行。

在“HelloWorld”应用程序的示例中,现成的过滤器如下所示:

<activity android:name=".HelloWorldActivity"
          android::label="@string/app_name">
    <intent-filter>
          <action android:name="android.intent.action.MAIN" />

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

Action 元素中的过滤器注册了将默认启动的 Activity。

Intent 过滤器根据特定原则工作。

在启动过程中,StartActivity 将 Intent 引导到一个 Activity。如前所述,如果有几个变量适合执行一个功能,用户可以从列表中选择需要的一个。

系统从扫描的应用程序中收集所有过滤器。与任务不对应的过滤器将从列表中删除。

如果 Intent 中指定的列表中没有任何任务与过滤器中指定的任务匹配,则将不匹配。除此之外,Intent 过滤器必须包含 Intent 中指定的所有类别。

来自 Intent 的 URI 会自动与 Intent 过滤器中的数据标签进行比较。如果没有匹配,过滤器将从列表中删除。

在新版本的 Android 操作系统中,Intent 过滤器的算法发生了变化。如果您按照旧的原则操作,代码将无法正常工作。

主要创新涉及 android:exported 参数。它有四个可以是真或假的元素。

不要在所有行上都设置为 true。我们将此参数用于启动程序块以启动应用程序。如果 Activity 使用 android.intent.action.view,我们也会应用它。它是必需的,以便我们可以使用其他应用程序运行程序。

使用隐式意图的示例

我们几乎在任何地方都使用 Intent。例如,这是一段代码,其任务是自动打开任何 URL:

val linkAddress: Uri = Uri.parse("https://developer.android.com")
val openLink = Intent(Intent.ACTION_VIEW, linkAddress)
startActivity(openLink)

我们在 Uri.parse 之后用引号和括号指定链接。

此外,我们可以强制 Android 在浏览器中打开“Android”一词的搜索查询:

val text = "Android"
val intent = Intent(Intent.ACTION_WEB_SEARCH)
intent.putExtra(SearchManager.QUERY, text)
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
}

这样的例子还有很多。我们可以使用 Intent 来处理设备的摄像头、麦克风、音频文件、系统设置以及 Android 操作系统的几乎所有元素。