【问题标题】:What exactly is intent.resolveActivity(getPackageManager()) doing?intent.resolveActivity(getPackageManager()) 到底在做什么?
【发布时间】:2019-04-14 15:25:45
【问题描述】:

我正在浏览the Android Developer Tutorials,遇到了一行我看不懂的代码。

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

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

我有几个问题。

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

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

3) 这实际上是我的主要问题。如果意图已经与要开始的课程相关联,为什么还要打扰intent.resolveActivity(getPackageManager())?它的documentation 指定如果返回一个类,它如何处理该类。好吧,返回一个类。但它返回的这个类在我的代码的任何一行都没有“合并”在我的intent 中,这让我认为Intent.ACTION_VIEW 已经以某种方式为我处理了它。

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

4) 另外,出于好奇,package manager class 里面是什么?我读到here,它就像一个应用程序数据目录。我这样说对吗?它保留了关于应用程序的哪些数据,我该如何访问它们。文档似乎没有多大帮助。

【问题讨论】:

    标签: java android android-intent


    【解决方案1】:

    但是这里创建了什么样的隐含意图?

    嗯...ACTION_VIEW Intent,查看请求的 URL。

    我是否可以将 Android 视为遍历我手机中的所有类并查看哪个具有可能处理数据的意图过滤器并创建意图结构以启动它找到的此类?

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

    它是简单地选择默认值还是要求用户选择它想要在哪个应用程序上运行?

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

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

    • 是否使用Intent.createChooser() 包装Intent 以强制选择器

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

    如果 Intent 已经链接到要启动的类,为什么还要使用 intent.resolveActivity(getPackageManager())?

    因为处理Intent 的活动可能为零。即使对于像 Web 浏览器这样常见的东西,特定用户也可能无法访问浏览器应用程序(辅助用户配置文件等)。如果你尝试启动一个活动,但没有匹配,你会得到一个ActivityNotFoundException,所以这个检查试图避免这样的异常。

    但是我说 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")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-30
        • 2010-12-30
        • 1970-01-01
        • 2014-03-20
        • 2019-06-14
        • 2023-03-15
        • 1970-01-01
        相关资源
        最近更新 更多