【Jetpack】学穿:Activity Results API(下)

简介: 【Jetpack】学穿:Activity Results API

② Fragment


同样跟下 registerForActivityResult()


网络异常,图片无法展示
|


最终调用 prepareCallInternal()


网络异常,图片无法展示
|


网络异常,图片无法展示
|


思路也很简单,想办法拿到 宿主Activity中的ActivityResultRegistry实例,调它的 register() 拿到返回的 ActivityResultLauncher实例引用。最后返回 新的ActivityResultLauncher 实例,在launch()中调用前面那个Activity的 ActivityResultLauncher实例引用 的launch()方法。TM调的是Activity的launch(),这一手 委托代理 玩挺6啊。


对了,这有个小细节,生命周期组件传入的是 Fragment.this,所以不用担心Fragment销毁没解绑导致的内存泄露问题。


③ 非Activity/Fragment 接收Activity结果


实现一个 LifecycleObserver 用于处理协定的注册和启动器的启动,代码示例如下:


网络异常,图片无法展示
|


调用处:


网络异常,图片无法展示
|


④ 亿点小细节:配置改变引起Activity重建的处理


ActivityResultRegistry 中还发现了介个:


网络异常,图片无法展示
|


好家伙,连配置更改导致重建的场景也考虑到了吗?


网络异常,图片无法展示
|


保存了:key(requestCode)相关的数据、处理结果、Random随机数实例。


网络异常,图片无法展示
|


requestCode和Result得以保留,Activity重建后,再把它们分发给新注册的Callback,避免了数据的丢失。


⑤ 亿点补充:测试Activity结果调用


默认情况下,registerForActivityResult() 会自动使用Activity提供的 ActivityResultRegistry,而它还提供了一个重载,支持传入自己的 ActivityResultRegistry 实例。能干嘛?拦截结果调用进行测试啊,不会另外启动另一个Activity。代码示例如下:


网络异常,图片无法展示
|


0x3、关于封装


Activity Results API 了解得七七八八了,接下来可以放心地用到项目中了,虽然它的API已经很简单易用了。但对于 喜欢偷懒到极致的开发仔 来说还是不够的,可以利用Kotlin相关的语法特性,封装下再少写一些代码。


捋下API使用链条:


  • registerForActivityResult()ActivityResultLauncher,需在ON_START或之前注册,在OnCreate()时再初始化会报错,还得传入一个**ActivityResultContract** 实例,最后跟一个 ActivityResultCallback 回调。
  • 调用 ActivityResultLauncher#launch() 才触发页面跳转,需要传入一个输入(如Intent)实例。


最简单的封装就是写几个 扩展方法,从ActivityResultLauncher生成和launch()调用处入手:


// 扩展
fun ComponentActivity.registerActResult(callback: ActivityResultCallback<ActivityResult>) =
    registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        callback.onActivityResult(it) }
fun Fragment.registerActResult(callback: ActivityResultCallback<ActivityResult>) =
    registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        callback.onActivityResult(it) }
fun Intent.launch(launcher: ActivityResultLauncher<Intent>) {
    launcher.launch(this)
}
// 注册处
private val mLauncher = registerActResult { 
    shortToast("收到测试数据:${it.data?.getStringExtra("value")}") 
}
// 调用处
Intent(this, SecondActivity::class.java).launch(mLauncher)


还可以在优化下,比如改成基于 ActivityResultCaller 进行扩展,然后把常用的一些跳转,如权限、打开相机、录像等写成一个个扩展函数,用的时候直接调用即可。懒得自己写或者想找参考的可以看看 → ActivityResult.kt


如果想代码写得更少更优雅,可以折腾得更复杂些,比如结合生命周期回调,各种简化调用的扩展,甚至弄成DSL调用等,具体可以参考这些:



怎么封装看自己,觉得适合就行,笔者就懒得整那么复杂了~


0x4、小结


借着重构BaseFragment的机缘巧合,过了波Activity Results API的用法,阅读源码了解到背后的实现原理,小试了一下封装。心里有底了,赶紧在重构项目的时候安排上!!!


参考文献:



相关文章
|
API Android开发
Android Activity Result API
Android Activity Result API
155 0
|
存储 缓存 自然语言处理
Jetpack 系列(3)—— 为什么 Activity 都重建了 ViewModel 还存在?
Jetpack 系列(3)—— 为什么 Activity 都重建了 ViewModel 还存在?
201 0
Jetpack 系列(3)—— 为什么 Activity 都重建了 ViewModel 还存在?
|
前端开发 API C++
相似度99%?Jetpack Compose 与 React Hooks API对比
众所周知Jetpack Compose设计理念甚至团队成员很多都来自React,在API方面参考了很多React(Hooks) 的设计,通过与React进行对比可以更好地熟悉Compose的相关功能。
427 0
|
API 开发者
【Jetpack】学穿:Activity Results API(中)
【Jetpack】学穿:Activity Results API
239 0
|
API 开发者
【Jetpack】学穿:Activity Results API(上)
【Jetpack】学穿:Activity Results API
213 0
|
安全 API Android开发
Jetpack:使用 ActivityResult 处理 Activity 之间的数据通信
本文先介绍ActivityResult的基本使用,最后会通过源码来探讨背后的原理。 在Android中,我们如果想在Activity之间双向传递数据,需要使用startActivityForResult启动,然后在onActivityResult中处理返回,另外申请权限也是类似的步骤。 但是这样的处理方式会让我们的代码变得非常复杂,并且也无法保证在 Activity 发送或接收数据时参数的类型安全。
446 0
|
6月前
|
存储 安全 Android开发
构建高效的Android应用:Kotlin与Jetpack的结合
【5月更文挑战第31天】 在移动开发的世界中,Android 平台因其开放性和广泛的用户基础而备受开发者青睐。随着技术的进步和用户需求的不断升级,开发一个高效、流畅且易于维护的 Android 应用变得愈发重要。本文将探讨如何通过结合现代编程语言 Kotlin 和 Android Jetpack 组件来提升 Android 应用的性能和可维护性。我们将深入分析 Kotlin 语言的优势,探索 Jetpack 组件的核心功能,并通过实例演示如何在实际项目中应用这些技术。
|
5月前
|
数据管理 API 数据库
探索Android Jetpack:现代安卓开发的利器
Android Jetpack是谷歌为简化和优化安卓应用开发而推出的一套高级组件库。本文深入探讨了Jetpack的主要构成及其在应用开发中的实际运用,展示了如何通过使用这些工具来提升开发效率和应用性能。
|
4月前
|
存储 数据库 Android开发
🔥Android Jetpack全解析!拥抱Google官方库,让你的开发之旅更加顺畅无阻!🚀
【7月更文挑战第28天】在Android开发中追求高效稳定的路径?Android Jetpack作为Google官方库集合,是你的理想选择。它包含多个独立又协同工作的库,覆盖UI到安全性等多个领域,旨在减少样板代码,提高开发效率与应用质量。Jetpack核心组件如LiveData、ViewModel、Room等简化了数据绑定、状态保存及数据库操作。引入Jetpack只需在`build.gradle`中添加依赖。例如,使用Room进行数据库操作变得异常简单,从定义实体到实现CRUD操作,一切尽在掌握之中。拥抱Jetpack,提升开发效率,构建高质量应用!
70 4
|
5月前
|
Android开发
Jetpack Compose: Hello Android
Jetpack Compose: Hello Android