• 赚钱入口【需求资源】限时招募流量主、渠道主,站长合作;【合作模式】CPS长期分成,一次推广永久有收益。主动打款,不扣量;

深入研究ActivityResult API-不再需要onActivityResult()

Android rin, seun 7个月前 (06-18) 343次浏览 0个评论

自2007年Android诞生以来,Activity它一直是其核心组件之一。应用程序中最常见的任务之一是在两个活动之间传输数据。直到现在,Intents并且onActivityResult是唯一的选择。

通过这两部分的结合,开发人员能够将数据从一个转移Activity到另一个,并轻松取回数据。

让我们通过一个示例进行详细说明:您的应用程序想要捕获图像并将其显示给用户。您可以编写自己的自定义相机,也可以委托通过来将图像获取到Android的任务Intents。在第二种情况下,Android系统将打开用户偏爱的Camera应用程序,捕获图像并将所需的数据通过调用onActivityResult()方法传递给您的活动。

传统方式— onActivityResult()方法

无论是Bitmap来自“相机”应用程序的图像还是来自图库的图像,或者可能是您来自其他应用程序“活动”的某些自定义结果,Android系统都会onActivityResult()在原始请求ActivityFragment类中调用方法。

如果您遇到一种捕获图像的情况,或者遇到多种情况,例如从图库中拾取图像,请求专项许可以及使用应用程序的其他屏幕处理您自己的自定义数据,那么这些操作的所有结果都只能通过一种方法处理onActivityResult()。而且此方法在您的代码中看起来像这样。

我觉得您根本不喜欢这种代码来读写。我也不会。因为这种代码会带来很多问题和有害错误,例如:

  • 紧耦合: 没有其他地方可以放置或抽象此代码和业务逻辑。就像您要分离“图像捕获”或“拾取图像”等每种情况一样。您无法这样做。您可以稍后委托,但是起点是这个。这将创建带有嵌套if-else块的类似于上述代码的错误群集。
  • 类型安全性:轻微的错误可能会导致数据类型错误。您可以将Integer值获取为String,然后花费数小时来调试为什么应用程序无法正常运行。这是因为您依赖String键来从Intent数据中放置/读取。您必须确保您为正确的密钥使用正确的类型。
  • 不需要的NullPointerException:谁不讨厌NullPointerException?如果您在输入时输入或输入数据时遇到错字Intent,则会NullPointerException在您的应用中发生炸弹般的崩溃。这可能会浪费大量时间,因为您可能会调试为什么数据为空。您如何认为您当时可能会错误地错过钥匙中的某些字母?

因此,Google为我们提供了一个解决方案,它的代码可读性更强,没有太多if-else块,每种情况下更少的耦合和分开的位置,键入安全性以确保正确的数据到达正确的方法,并且绝对不会NullPointerException由于错别字而出现。

引入ActivityResult API-新方法

我不确定Google正式宣布此名称后会如何称呼,但本文将其称为Activity Results API。

从…开始 Activity 1.2.0-alpha02 和 Fragment 1.3.0-alpha02,您现在有了一个不错的抽象,可以处理 onActivityResult() 在非常干净且可重复使用的结构中使用该方法。

让我们看看如何使用这个新的API。

添加依赖项

首先,您必须在应用程序的build.gradle文件中添加以下依赖项。

请注意,在写这篇文章的时候,最新的版本是1.2.0-alpha04activity-ktx1.3.0-alpha04fragment-ktx。您可以通过Google Maven链接检查最新版本。这些API尚处于Alpha阶段,因此API尚未最终确定。这些可以随时更改。本文适用于alpha04版本,但可能适用于早期版本或更高版本。

ActivityResult API流程

使用此新API的过程如下所示。

深入研究ActivityResult API-不再需要onActivityResult()

1.创建Contract

首先,您必须定义合同或使用任何现有合同。Contract是ActivityResultContract接口的实现,规定可以使用I类型的输入调用活动并产生O类型的输出。

如下示例SimpleContract,该示例将Integer作为输入并从子Activity返回一些String数据。

createIntent()方法用于创建有效的IntentstartActivityForResult()一旦调用此合同,该有效方法将在方法中传递。该parseResult()方法将充当方法的代理,onActivityResult()并正在解析结果Intent并从中提取数据。

您可以看到我们不再需要将一堆if-else块放入onActivityResult()方法中。因为每种情况将在单独的实现和单独的parseResult()方法中这样处理。这就是Activity Results API的美丽和简单。

2.注册

下一步是向SimpleContract活动结果API 注册。这是通过调用registerForActivityResult()方法完成的。

请注意,在以前的版本中alpha02alpha03,这种方法被称为prepareCall()。但是,在alpha04此,它被重命名为registerForActivityResult()

您会看到注册合同有多容易。而且,借助备受喜爱的Kotlin的简单性,您将可以通过一个很好的lambda方法获得结果。这将parseResult()在合同中的方法之后调用,并将为您提供结果(在我们的示例中为可为null的String)。您可以检查NULL值以查看用户是否取消了该操作或结果是否RESULT_OK来自子活动。

3.调用Contract

最后,您要做的就是调用simpleContractRegistration上面代码片段中的这个新注册变量。像任何普通方法一样继续调用它。您在合同中定义的所有输入都将在方法调用中作为类型安全参数传递。

和瞧。onActivityResult()现在没有了。您可以轻松地将其与您自己的自定义ActivityFragment类一起使用,并且它将是带有类型安全参数的非常干净,有条理和可重用的代码。

预建Contract

既然您已经知道使用活动结果API和创建自己的Contract是多么简单。您将非常高兴得知Google提供了一些非常有用的预建Contract。这些可以从ActivityResultContracts 类。 让我们在下面探索一些例子。

捕获图像— ActivityResultContracts.TakePicture()

您可以轻松地从Camera捕获图像,而无需担心Media Intent。

选择图像— ActivityResultContracts.GetContent

这样,您不仅可以选择图像,还可以从设备中选择其他文件。您mimeType必须在应用程序中提供所需的文件。

请求单/多权限

现在,这是我最喜欢的一个。我记得我不得不写100行代码来要求多个权限来处理非常复杂的流程。当没有活动结果API时,我已经在本文中详细介绍了它。

没有任何第三方库的Android中的多个运行时权限

在此分步教程中了解有关添加多个运行时权限的信息

medium.com

活动结果API提供了两种方法- RequestPermissionRequestMultiplePermissions。这两个名称完全相同。这是一个简单的示例代码。

示范代码

我创造了 一个带有一些示例合同的简单演示项目如本文有关以下Github存储库的讨论。您可以探索更多内容并使用它。

wajahatkarim3 / ActivityResultsDemo

一个演示项目,可在Android中尝试使用新的Activity Results API-wajahatkarim3 / ActivityResultsDemo

github.com

结论

现在结束语,在本文中,我们讨论了传统onActivityResult()方式中的一些问题。然后,我们学习了新的Activity Results API。然后,我们创建了一个示例合同,以查看不同部分如何协同工作。最后,我们看到了一些预先建立的合同,例如图像捕获,挑选图像,权限处理等。

Wajahat Karim的Android提示

使用Wajahat Karim手工制作的资源,学习有关Android开发的初学者和高级技巧与教程。

wajahatkarim.substack.com

喜欢 (2)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址