intent.resolveActivity(getPackageManager())究竟在做什么?

2022-09-03 12:39:52

我正在浏览Android开发人员教程,我遇到了一行我不理解的代码。

这是代码行(可在 Android 开发人员教程的第 4 页上找到)。

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

我有几个问题。

1)文档说它只是向用户显示数据。我知道它选择的应用程序将取决于要显示的数据类型。例如,在这种情况下,网页被解析为 uri 数据类型。但是,这里正在创造什么样的隐含意图呢?在后端,我是否可以将Android视为遍历手机中的所有类,并查看哪一个具有可能处理数据的意图过滤器并创建意图结构以启动它找到的这个类?Intent.ACTION_VIEW

2)如果它找到多个可以处理这个问题的类会发生什么?它是简单地选择默认值还是要求用户选择要在其中运行的应用?当我在手机上运行代码时,它只是默认启动三星互联网应用程序。

3)这实际上是我的主要问题。如果意图已经链接到一个类开始,那么为什么要打扰呢?其文档指定在返回类时如何处理该类。好了,返回一个类。但是,它返回的这个类也没有“并入”在我的代码的任何一行中,这让我认为它已经以某种方式为我处理了它。intent.resolveActivity(getPackageManager())intentIntent.ACTION_VIEW

这将是一个飞跃,但是我说运行或其他函数做类似的并以某种方式将它返回的类合并到我的意图中是正确的吗?Intent.ACTION_VIEWintent.resolveActivity(getPackageManager())

4)另外,出于好奇,包管理器类内部有什么?我在这里读到它就像一个应用程序数据的目录。我这么说是对的吗?它保留了有关应用程序的哪些类型的数据,以及我如何访问它们。文档似乎没有多大帮助。


答案 1

但是,这里正在创造什么样的隐含意图呢?

嗯......一个 ,以查看请求的 URL。ACTION_VIEWIntent

我可以把Android想象成遍历我手机中的所有类,看看哪一个具有可能处理数据的意图过滤器,并创建意图结构来启动它找到的这个类?

活动在清单中登记。操作系统基本上具有所有已注册活动及其详细信息的数据库,并且它使用该数据库来查找任何给定隐式的候选项 。<intent-filter>Intent

它是简单地选择默认值还是要求用户选择要在其中运行的应用?

这取决于多种因素,包括:

  • 用户是否为此类选择默认处理程序(例如,选择默认 Web 浏览器)Intent

  • 是否包装强制选择器的用法IntentIntent.createChooser()

  • 应用是否已为 URL 注册了应用链接

如果意图已经链接到一个类来启动,那么为什么要为意图.resolveActivity(getPackageManager())而烦恼呢?

因为可能没有活动来处理 .即使对于像 Web 浏览器这样常见的浏览器,特定用户也可能无权访问浏览器应用(辅助用户配置文件等)。如果您尝试启动一个活动,但没有匹配项,则会收到一个 ,因此此检查试图避免此类异常。IntentActivityNotFoundException

但是我说Intent.ACTION_VIEW运行 intent.resolveActivity(getPackageManager()) 或其他执行类似操作并以某种方式将其返回的类合并到我的意图中的函数是否正确?

没有。更准确地说,查询我提到的数据库,看看什么将处理 ,如果有的话。resolveActivity()Intent

包管理器类中有什么?

一点点Java代码。它主要是指向核心操作系统进程的IPC网关,用于查询已安装应用程序的数据库,其功能等。


答案 2

顺便说一句,此方法可以在Android 11及更高版本上返回null,这是由添加的新限制引起的:https://developer.android.com/about/versions/11/privacy/package-visibility 因此要解决此问题,我们必须在清单下添加查询:

<queries>
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https" />
    </intent>
</queries>

不要忘记更新gradle插件,以防找不到查询项:

classpath("com.android.tools.build:gradle:3.5.4")

推荐