替代startActivityForResult的官方解决方案–ActivityResultAPI

当我接触到startActivityForResult的时候,我发现它已经被官方弃用了,我在官方看到这样的一句话

虽然所有API级别的Activity类均提供底层 [startActivityForResult()](https://developer.android.com/reference/android/app/Activity#startActivityForResult(android.content.Intent, int))和 [onActivityResult()](https://developer.android.com/reference/android/app/Activity#onActivityResult(int, int, android.content.Intent)) API,但我们强烈建议您使用 AndroidX ActivityFragment 中引入的Activity Result API

这也就说明官方是希望我们使用Activity Result API进行开发的

参考:https://segmentfault.com/a/1190000037601888

官方文档:https://developer.android.com/training/basics/intents/result

针对actibity注册回调

位于 ComponentActivityFragment 中时,Activity Result API 会提供 [registerForActivityResult()](https://developer.android.com/reference/androidx/activity/result/ActivityResultCaller#registerForActivityResult(androidx.activity.result.contract.ActivityResultContract, androidx.activity.result.ActivityResultCallback)) API,用于注册结果回调。registerForActivityResult() 接受 ActivityResultContractActivityResultCallback 作为参数,并返回 ActivityResultLauncher,供您用来启动另一个 activity。

ActivityResultContract 定义生成结果所需的输入类型以及结果的输出类型。这些 API 可为拍照和请求权限等基本 intent 操作提供默认协定。您还可以创建自己的自定义协定

ActivityResultCallback 是单一方法接口,带有 onActivityResult() 方法,可接受 ActivityResultContract 中定义的输出类型的对象:

可能一些人觉得这是官网照搬下来的,没有什么意义,可是事实上我只理解这三段话,我觉得够用了,不过以后还会继续深入。那么就让我现在来给讲一下这三段话的意思

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//创建一个启动者ActivityResultLauncher是必要的
private ActivityResultLauncher activityResultLauncher =
//给ActivityResultLauncher进行注册,此时registerForActivityResult会接受两个参数ActivityResultContract和ctivityResultCallback,代码中的IO为当前活动传入的数据类型和第二活动传出的输出数据类型
registerForActivityResult(new ActivityResultContract<I, O>() {
@NonNull
@Override
public Intent createIntent(@NonNull Context context, I input) {
//在这个方法中,去创建intent以启动第二活动,当然也可以.putExtra("key", input),这里给了input参数,即需要传入的数据,input可以在调用activityResultLauncher.lsunch()时给input赋值
return new Intent(MainActivity.this, Activity2.class);
}

@Override
public O parseResult(int resultCode, @Nullable Intent intent) {
//在这个方法中,它会帮你得到传回的intent,然后可以使用它去解析数据
O s = intent.getStringExtra("address");
if (resultCode == Activity.RESULT_OK && s != null)
return s;
else
return null;
}
}, new ActivityResultCallback<O>() {
@Override
public void onActivityResult(O result) {
//这个方法是当第二活动销毁时,数据回调了,需要做什么动作,这里的result由系统自动调用parseResult方法得到
editText.setText(result);
}
});

好,那怎么真正的去使用它呢,只需要在主活动方法中使用activityResultLauncher.launch(null);如果不进行传入数据,则为null

那么如果需要传入数据,怎么在第二活动得到这个数据呢,getIntent().getStringExtra("key");去得到传入的数据

如果需要传回数据,则可以getIntent().putExtra("key", "value");此时需要设置返回代码以及intent,setResult(Activity.RESULT_OK, getIntent());

至此就可以简单的使用Activity Result API了,当然他不局限于在内部活动传递字符串等数据,就行官网所说

您的应用可启动相机应用并接收拍摄的照片作为结果。或者,您可以启动“通讯录”应用以便用户选择联系人,并且您将接收联系人详细信息作为结果。