全面拥抱Activity Results API来替代onActivityResult

3,303 阅读4分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金

前言

随着应用的扩展,onActivityResult回调方法各种嵌套、耦合严重、难以维护;

在google最新的activity-ktx beta版本中已经废弃了原onActivityResult方法,推荐使用Activity Results API来处理页面数据的处理;

通过新的 Activity Result API,我们可以单独的类中处理结果回调,真正做到单一职责;

今天我们就来介绍下

本文已在公众号【Android开发编程】发表

一、activity results api介绍和使用方法

1、什么是results api

  • Activity Results API 是 Google官方推荐的Activity、Fragment获取返回结果的方式。ActivityResultContract是一个抽象类,也是我们需要定义的协议,它需要去定义如何传递数据和如何处理返回的数据;

  • 相当于原startActivityForResult 和onActivityResult方法;

2、使用步骤

主要用到两个组件

  • ActivityResultContract: 协议,它定义了如何传递数据和如何处理返回的数据;

  • ActivityResultLauncher: 启动器,调用ActivityResultLauncher的launch方法来启动页面跳转,作用相当于原来的startActivity();

2.1在app下的build.gradle中加入依赖

implementation 'androidx.activity:activity-ktx:1.2.0-beta01'implementation 'androidx.fragment:fragment-ktx:1.3.0-beta01'

2.2首先自定义一个ActivityResultContract,实现两个activity互传的数据处理

class MyActivityResultContract : ActivityResultContract<String, String?>() {    override fun createIntent(context: Context, input: String?): Intent {        return Intent(context, SecondActivity::class.java).apply {            putExtra("input", input)        }    }    override fun parseResult(resultCode: Int, intent: Intent?): String? {        val data = intent?.getStringExtra("result")        return if (resultCode == Activity.RESULT_OK && !TextUtils.isEmpty(data)) data else null    }}调用registerForActivityResult方法,注册刚刚定义的contract协议,返回一个activityResultLauncher对象。  val activityResultLauncher = registerForActivityResult(MyActivityResultContract()) {            Toast.makeText(this, "result value is :${it}", Toast.LENGTH_LONG).show()        }

2.3 用返回的launcher对象启动另一个activity界面

 btn_start_second.setOnClickListener {            activityResultLauncher.launch("second activity start")   }

3、使用内置的 ActivityResultContract来进行页面跳转

还可以通过ActivityResultContracts类来调用谷歌为我们内置的Contract,其中包含来各种常用的Contract

  • @StartActivityForResult: 通用的Contract,不做任何转换,Intent作为输入,ActivityResult作为输出,这也是最常用的一个协定;

  • @RequestMultiplePermissions:用于请求一组权限;

  • @RequestPermission: 用于请求单个权限;

  • @TakePicturePreview: 调用MediaStore.ACTION_IMAGE_CAPTURE拍照,返回值为Bitmap图片

  • @TakePicture: 调用MediaStore.ACTION_IMAGE_CAPTURE拍照,并将图片保存到给定的Uri地址,返回true表示保存成功;

  • @TakeVideo: 调用MediaStore.ACTION_VIDEO_CAPTURE 拍摄视频,保存到给定的Uri地址,返回一张缩略图;

  • @PickContact: 从通讯录APP获取联系人;

  • @GetContent: 提示用选择一条内容,返回一个通过ContentResolver#openInputStream(Uri)访问原生数据的Uri地址(content://形式) 。默认情况下,它增加了Intent#CATEGORY_OPENABLE, 返回可以表示流的内容;

  • @CreateDocument: 提示用户选择一个文档,返回一个(file:/http:/content:)开头的Uri。

  • @OpenMultipleDocuments: 提示用户选择文档(可以选择多个),分别返回它们的Uri,以List的形式;

  • @OpenDocumentTree: 提示用户选择一个目录,并返回用户选择的作为一个Uri返回,应用程序可以完全管理返回目录中的文档;

    private val activityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (it.resultCode == RESULT_OK) { val result = intent?.getStringExtra("result") tvName.text = result } } btnStartSecond.setOnClickListener { //点击跳转到SecondActivity val intent = Intent(this, SecondActivity::class.java) intent.putExtra("name", "我是第一个页面传过去的参数") activityResultLauncher.launch(intent) }

使用系统内置的ActivityResultContract可以很方便的实现页面间传值来

总结

使用activity results api替代传统的onActivityResult方法,可以简化我们的代码,提高代码的重用性;一起加油

Android进阶之后台任务和定时服务,放弃AlarmManager全面拥抱WorkManager

Android转场动画深度解析

Java进阶之深入理解负载均衡的5种算法实现原理

Android进阶之Coil-为kotlin而生的图片库详解

历史推荐,共勉

Android进阶之view坐标系全面详解

国庆快乐:一起学习进步

精彩推荐

Java线程并发之AQS原理机制全面详解

多线程之AsyncTask使用详解和从源码中深入理解AsyncTask机制

**Android高手进阶之多线程HandlerThread使用和源码分析详解
**

Android源码进阶之轻松搞定FlexboxLayout弹性布局原理机制

Java进阶:线程并发之深入理解CAS机制详解

Android进阶之深入理解View的布局(Layout)流程原理

Android进阶之深入理解View的测量(Measure)流程机制

Android进阶:深入理解Android窗口管理框架机制

Android高手进阶之彻底了解DiskLruCache磁盘缓存机制原理

Java高进进阶之FastThreadLocal源码详解(修复ThreadLocal的缺陷)

Java高级进阶之String实现源码详解

Java线程进阶之ThreadPoolExecutor线程池执行原理机制详解

Android架构进阶之深入理解AppStartup原理

Android源码进阶之ViewDragHelper原理机制解析

Android源码进阶之深入理解Retrofit工作原理

前端进阶之JS运行原理和机制详解

源码进阶之lifecycle组件原理分析

Android进阶之彻底理解LruCache缓存机制原理

Android源码进阶之Glide生命周期管理机制详解

Android源码进阶之Glide加载流程和源码详解