背景
在Android应用程序开发中,启动一个Activity不一定是单项操作,从启动的Activity获取数据是常见的场景,最传统的方式是通过Intent携带数据,然后使用startActivityForResult方法来启动下一个Activity,然后通过onActivityResult来接收返回的结果,代码如下:
- 调用startActivityForResult方法启动
<pre language="javascript" code_block="true"> startActivityForResult(intent,1)
- 实现onActivityResult方法
<pre language="javascript" code_block="true">override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(resultCode == 1 && resultCode == Activity.RESULT_OK){
// 处理第二个页面带回的数据
}
}
以上方式,onActivityResult就能获取从上一个界面返回的数据,这种方式非常有用,不仅能同一个应用中,也可以从其他应用中获取数据,比如我们常见的,调用系统相机、相册获取照片,获取系统通讯录等。
但也有一些问题…
随着应用的扩展,onActivityResult回调方法各种嵌套、耦合严重、难以维护。 最常见的场景就是调用系统相机相册获取照片了。代码可能像是如下这样:
<pre language="javascript" code_block="true">class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_PERMISSION -> {
// 处理权限
}
REQUEST_CAMERA -> {
// 相机获取图片结果
}
REQUEST_ALBUM -> {
// 相册获取图片结果
}
REQUEST_CROP -> {
// 系统裁剪
}
}
}
super.onActivityResult(requestCode, resultCode, data)
}
companion object {
const val REQUEST_PERMISSION = 1001
const val REQUEST_CAMERA = 1002
const val REQUEST_ALBUM = 1003
const val REQUEST_CROP = 1004
}
}
各种处理结果都耦合在onActivityResult回调里,并且还得定义一堆额外的常量REQUEST_CODE,用与判断是哪个请求的回调结果。
onActivityResult 现状?
Google 可能也意识到onActivityResult的这些问题,在androidx.activity:activity:1.2.0-alpha02 和androidx.fragment:fragment:1.3.0-alpha02 中,已经废弃了startActivityForResult和onActivityResult方法。
<pre language="javascript" code_block="true"> /**
* {@inheritDoc}
*
* @deprecated use
* {@link #registerForActivityResult(ActivityResultContract, ActivityResultCallback)}
* passing in a {@link StartActivityForResult} object for the {@link ActivityResultContract}.
*/
@Override
@Deprecated
public void startActivityForResult(@SuppressLint("UnknownNullness") Intent intent,
int requestCode)