RegisterForActivityResult介绍
registerForActivityResult是Google提供的,用来取代startActivityForResult的方法,通过registerForActivityResult,我们可以将每一次与其他界面的交互给封装到单独的地方。
registerForActivityResult基础介绍
public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
@NonNull ActivityResultContract<I, O> contract,
@NonNull ActivityResultCallback<O> callback) {
}
registerForActivityResult的入参分为ActivityResultContract与ActivityResultCallback。
ActivityResultContract,主要是用来定义传给其他界面的参数以及其他界面返回的参数解析
ActivityResultCallback,主要用来获取解析以后的参数
ActivityResultLauncher,registerForActivityResult的返回值,主要用来传递参数以及打开新的Activity
举个例子
ActivityResultLauncher<Integer> launcher = registerForActivityResult(new ActivityResultContract<Integer, String>() {
@Override
public String parseResult(int resultCode, @Nullable Intent intent) {
return intent.getStringExtra("test");
}
@NonNull
@Override
public Intent createIntent(@NonNull Context context, Integer input) {
Intent intent = new Intent();
intent.setClass(context, MainActivity2.class);
intent.putExtra("TEST", input);
return intent;
}
}, new ActivityResultCallback<String>() {
@Override
public void onActivityResult(String result) {
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
}
});
//启动新的界面并传递参数
launcher.launch(9999);
ActivityResultContract使用泛型定义了入参与出参,然后在createIntent中创建了需要打开的Intent对象,在parseResult中可以获取到resultCode与intent,其中就可以获取到参数,最后解析的结果,则是通过ActivityResultCallback返回。
需要注意的是:registerForActivityResult必须要在onResume之前调用,不然会抛出异常崩溃
更多惊喜
通过上面的代码,其实已经将传递并获取参数封装到ActivityResultLauncher对象中了,不过系统为我们做的更多,比如上面的例子就可以改成
ActivityResultLauncher<Intent> launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
Log.i(TAG, "onActivityResult: " + result.getResultCode());
Log.i(TAG, "onActivityResult: " + result.getData());
}
});
//启动并传递需要启动的Intent
launcher.launch(new Intent(this,MainActivity2.class));
通过ActivityResultContracts中为我们封装的方法,我们可以很轻松的完成文件选择、权限申请,具体如下图所示
示例:申请权限
ActivityResultLauncher<String> requestPermission = registerForActivityResult(new ActivityResultContracts.RequestPermission(),
new ActivityResultCallback<Boolean>() {
@Override
public void onActivityResult(Boolean result) {
//true/false返回时候有权限
if (!result) {
//是否需要提示用户然后再申请
boolean b = ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE);
//其他逻辑
}
}
});
示例:选择文件
ActivityResultLauncher<String[]> chooseFileLauncher = registerForActivityResult(new ActivityResultContracts.OpenDocument(),
new ActivityResultCallback<Uri>() {
@Override
public void onActivityResult(Uri result) {
}
});
更多可以查看ActivityResultContracts源码
需要注意的是,不能在Fragment/Activity Resume以后调用registerForActivityResult,不然会爆出异常