RegisterForActivityResult介绍

/ 0评 / 1

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中为我们封装的方法,我们可以很轻松的完成文件选择、权限申请,具体如下图所示

file

示例:申请权限

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,不然会爆出异常

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注