4、registerForActivityResult 向上一个活动传递数据
startActivityForResult 的替代方案registerForActivityResult
4.1 设计思路
大致思路:先向下传递一个Intent,向下的activity操作这个Intent后再次将这个Intent返回给上一个activity。
既然需要使用新的功能,那么我们就必须要先了解以下,刚说到的ActivityResultLauncher
、ActivityResultContract
、ActivityResultCallback
到底是些什么东西
- ActivityResultLauncher 从字面意思其实就能很好理解,可以理解它就是一个Activity的启动器,它的作用就是承载启动对象与返回对象,通
registerForActivityResult
返回该对象,这时并不会立即启动另一个Activity。 - ActivityResultContract 是用来协定所需的输入类型以及结果的输出类型,Android默认提供了一些常用的定义,例如上面所使用到到
ActivityResultContracts.StartActivityForResult()
。当然这里你也可以通过继承ActivityResultContract
实现自己的定义。 - ActivityResultCallback 通过名字就可以了解到这是启动Activity并返回到当前Activity时的结果回调。
4.2 设计ActivityResultLauncher
根据上面的流程图我们可以知道首先先实现ActivityResultLauncher
,java实现代码如下:
private ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
//判断是否传入正确的result
if(result.getResultCode() == RESULT_OK){
Intent intent = result.getData(); //获取上一个活动返回的Intent
//判断上一个活动的Intent是否存在,存在则在日志中输入
if(intent != null){
String str = intent.getStringExtra("data_return");
Log.d("DATA",str);
}
}
}
});
通过这段代码我们可以看到使用了registerForActivityResult
这个方法,传递了两个参数。
4.2.1 registerForActivityResult() 方法解析
registerForActivityResult() 方法接收两个参数。
第一个参数是一种 Contract 类型。
Contract 用于指定一个 Activity 被调用时,使用 I 类型的输入,产生 O 类型的输出。
第二个参数是回调。即当存在返回值时,处理返回结果的代码。用 lambda 表达式来实现
在实现一个 Activity 向上一个 Activity 传递数据的需求中第一个参数可以传入 ActivityResultContracts.StartActivityForResult()
该对象的 输入类型 I 为 Intent
,输出类型 O 为 ActivityResult
4.3 向下传递Intent
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(activityMainBinding.getRoot());
Button button = (Button) activityMainBinding.button1;
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
//向下传递Intent
resultLauncher.launch(intent);
}
});
}
4.4 下一个活动接收Intent
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMain2Binding binding = ActivityMain2Binding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
View button = binding.button2;
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//获取前一个活动传递的Intent
Intent intent = getIntent();
//给这个Intent封装value
intent.putExtra("data_return","xupt3G");
//返回活动的结果
setResult(RESULT_OK,intent);
Toast.makeText(getApplicationContext(),"已经返回结果", Toast.LENGTH_SHORT).show();
finish();
}
});
}
setResult()方法接收两个参数,第一个参数用于向上个活动返回处理结果,一般只使用RESULT OK或RESULT_CANCELED这两个值,第二个参数则把带有数据的Intent传递回去。
现在当我们返回上一个活动时就会正常返回值了。