Android隐式意图 VS 显式意图

78

在使用 Android 开发时,我意识到隐式意图由于其灵活性,在大多数情况下都是一个不错的选择。但是对于显式意图呢?使用它们有什么好处?哪些情况下使用它们是一个好的实践?

涉及到 IT 技术相关内容时,隐式意图由于其灵活性通常是个不错的选择,而在某些情况下,显式意图也会更加适合。当需要明确指定应用组件并精确控制操作时,可以使用显式意图。例如,在应用程序之间共享数据或启动内部应用程序组件时,显式意图通常较为常见。


2
给未来的读者一个提示:隐式意图也被称为常见意图 - RBT
9个回答

156

隐式意图不直接指定应该调用哪个Android组件,它只指定要执行的操作。可以使用Uri与隐式意图一起使用以指定数据类型。

例如

Intent intent = new Intent(ACTION_VIEW,Uri.parse("http://www.google.com"));

这将导致网页浏览器打开一个网页。 Android系统会搜索为特定操作和数据类型注册的所有组件。如果找到多个组件,则用户可以选择要使用的组件。

明确意图用于应用程序本身中的其中一个活动可以切换到另一个活动...例如 Intent intent = new Intent(this,Target.class); 这会导致从当前上下文切换到目标活动。 明确意图也可以使用 putExtra 方法将数据传递给其他活动,并通过 getIntent().getExtras() 方法检索目标活动。

希望这有所帮助。


6
隐式意图的另一个例子是相机意图,相机意图将提示打开相机,可以是手机中安装的任何相机应用程序。 - Sreekanth Karumanaghat

29

通常情况下,您在自己的应用程序中使用显式意图来启动活动。此时,您已经知道要启动哪个活动,因此没有必要设置隐式意图。


26

关键词:你知道和你不知道的时候

显式意图:

当您确切知道哪个Activity可以处理您的请求时,请使用显式意图。

例如:您有一个列表Activity,当您点击列表中的项目时,它会打开详细信息Activity。在这种情况下,您知道该项的详细信息可以由应用程序的DetailActivity.class显示或处理。 因此,要执行此操作,您需通过显式指定类名创建一个Intent。

Intent showDeatil = new Intent(this,DetaiActivy.class);  
startActivity(showDeatil);

隐式意图(Implicit Intent):

当您不知道哪个应用程序的哪个活动可以处理您的请求时,请使用隐式意图。

例如:您有一个链接。当您单击该链接时,它应该在某个浏览器中打开网页。 您并不知道哪个应用程序中的哪个活动可以处理您的请求。您只是有一个模糊的想法,即这是一个网页链接,因此当有人打开它时,应该在某个浏览器中打开网页。在这种情况下,您只需指定操作,然后操作系统会处理其余部分。

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);

BONUS:

操作系统如何决定?

有一个术语称为Intent Resolution(意图解析)。
在Intent解析中:

  • 操作系统提取你的intent中指定的ACTION。

  • 进入包管理器,并查找所有已安装在设备上与匹配ACTION的注册活动。

  • 在弹出窗口中显示所有匹配应用程序的列表。

编写隐式意图的更安全方法。

有时可能没有与ACTION匹配的Activity,这种情况下会收到NullPointerException。因此,更可取的方式是:

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}

如何让你的应用程序出现在弹出列表中?

假设你已经编写了一些浏览器应用程序。如果你希望当某人打开链接时,你的应用程序能够出现在弹出列表中,那么你需要在AndroidManifest.xml文件中使用Intent Filters注册你的Activity。像这样。

<application
    .....  >

    ......
    <activity android:name=".YourBrowserActivity">
        <action android:name="android.intent.action.VIEW" />       
        <data android:scheme="http" android:host="www.example.com" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
    </activity>
 ..... 


</application>

参考资料
常见 Intent 操作及其 Intent 过滤器列表
更多关于 Intent 过滤器和 Intent 分辨的信息


1
讲解得非常清楚!赞一个! - Tom Taylor

23
  1. 明确的意图用于调用特定组件。当您知道要启动哪个组件,且不希望让用户自由控制使用哪个组件时使用。例如,您有一个包含2个活动(Activity A和Activity B)的应用程序。您想从Activity A启动Activity B。在这种情况下,您需要定义一个针对Activity B的明确意图,并直接调用它。

  2. 隐式意图用于当您知道要执行什么操作,但不确定应该启动哪个组件时。或者如果您想让用户在一组组件中自由选择。如果将这些意图发送到Android系统,则会搜索所有已注册特定操作和数据类型的组件。如果只找到一个组件,则Android会直接启动该组件。例如,您的应用程序使用相机拍摄照片。您的应用程序的一个功能是允许用户发送他拍摄的照片。您不知道用户有哪种可以发送照片的应用程序,而且如果用户有多个应用可以使用,则还想为用户提供选择外部应用程序的选项。在这种情况下,您不应使用明确意图。而是应该使用其操作设置为ACTION_SEND并且数据extra设置为照片URI的隐式意图。

    明确意图始终传递到其目标,无论它包含什么;不会查看过滤器。但是,仅当隐式意图可以通过组件的一个过滤器时,才将其传递给该组件。


14

1) 显式意图:指定了在Intent中开发者知道的组件名称。

2) 隐式意图:在Intent中未指定组件名称。


2
问题明确要求使用案例。定义是不够的。 - Marco Faustinelli

5

来自文档

有两种类型的意图:

  • 显式意图按名称(完全限定类名)指定要启动的组件。通常,您会使用显式意图启动您自己应用程序中的组件,因为您知道要启动的活动或服务的类名。例如,您可以在响应用户操作时启动新的活动,或在后台启动服务以下载文件。
  • 隐式意图不命名特定组件,而是声明要执行的一般操作,这允许另一个应用程序的组件处理它。例如,如果您想在地图上向用户显示位置,则可以使用隐式意图请求另一个能够显示指定位置的应用程序。

3

我们可以简单地描述这两种意向...

显式意向:它们用于同一应用程序内部的通信。

例如:考虑一个具有登录页面的应用程序,其中包含两个字段(用户名和密码)。如果两者均正确,则会将我们带到显示先前输入的用户名字段的页面。在这种情况下,我们使用显式意向,因为我们需要更改活动并在同一应用程序中从一个活动传递数据到另一个活动(用户名字段)。

隐式意向:它们用于跨越两个不同应用程序的通信。

例如:考虑一个应用程序,它使用用户从相机中获取的图像作为个人资料图片。为此,它使用隐式意向。它会调用相机应用程序的意图来获取图片。

希望您能理解。


2
  1. 隐式意图 - 当我们想要通过意图调用系统组件来执行特定任务,但实际上并不知道要使用的组件名称时,Android系统将显示所需的应用程序列表以执行该任务。
  2. 显式意图 - 当我们想要使用完全限定名称调用另一个活动,并且当然我们知道该活动的名称时。

1

隐式意图

  • 它可以在不指定要打开哪个应用程序的情况下,打开新的应用程序。
  • 它仅指定要执行的操作,而不直接指定Android组件。
  • URI可与隐式Intent一起使用以指定数据类型。

显式意图

  • 在编写代码时,它将打开特定的应用程序。
  • 它用于应用程序本身,其中一个活动可以切换到另一个活动。
  • 使用putExtra方法将数据传递到其他活动,并通过目标活动的getIntent()检索。
  • 即使未查询过滤器,它也始终传递到目标。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接