Activity Results API

onActivityResult的现状
  • 回调方法各种嵌套、耦合严重、难以维护
  • 处理结果都耦合在onActivityResult回调中
  • 定义许多额外的常量来处理返回结果
Activity Results API
  • Activity Results API 是 Google官方推荐的Activity、Fragment获取返回结果的方式。
一、Activity Results API 中两个重要的组件:

ActivityResultContract和ActivityResultLauncher。

  • ActivityResultContract: 协议,它定义了如何传递数据和如何处理返回的数据。ActivityResultContract是一个抽象类,你需要继承它来创建自己的协议,每个 ActivityResultContract 都需要定义输入和输出类,如果您不需要任何输入,可使用 Void作为输入类型。
  • ActivityResultLauncher: 启动器,调用ActivityResultLauncher的launch方法来启动页面跳转,作用相当于原来的startActivity()
二、如何使用
  • 首先再build.gradle中添加依赖
 implementation 'androidx.activity:activity:1.2.0-beta01'
 implementation 'androidx.fragment:fragment:1.3.0-beta01'
  • 在Activity中新建内部类,继承ActivityResultContract
class ResultContract extends ActivityResultContract<String, String> {
    @NonNull
    @Override
    public Intent createIntent(@NonNull Context context, String input) {
        Intent intent = new Intent(ResultActivity.this, ResultBackOneActivity.class);
        intent.putExtra("text_string", input);
        return intent;
    }

    @Override
    public String parseResult(int resultCode, @Nullable Intent intent) {
        return intent.getStringExtra("one_back");
    }
}
  • 然后初始化ActivityResultLauncher,在回调方法中可以获取到带回来的值 result
ActivityResultLauncher launcher = registerForActivityResult(new ResultContract(), new ActivityResultCallback<String>() {
    @Override
    public void onActivityResult(String result) {
        Toast.makeText(ResultActivity.this, result, Toast.LENGTH_SHORT).show();
    }
});
  • 然后在跳转方法中使用launcher进行页面见传值,使用.launcher()方法启动
tv_intent_one.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            launcher.launch("这里是第一个跳转");
        }
});
  • 在目标页面中,处理还是一样的,返回数据时也是之前的操作
   TextView tv_intent_one = findViewById(R.id.tv_intent_one);
   tv_intent_one.setText(getIntent().getStringExtra("text_string"));
   tv_intent_one.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            setResult(RESULT_OK, new Intent().putExtra("one_back", "这里是第一个跳转的返回"));
            finish();
        }
   });
三、使用预定的Contract

为了使用方便,Google预定义了许多类型

  • StartActivityForResult: 通用的Contract,不做任何转换,Intent作为输入,ActivityResult作为输出,这也是最常用的一个协定。
  • RequestMultiplePermissions:用于请求一组权限
  • RequestPermission:用于请求单个权限
  • TakePicturePreview:调用MediaStore.ACTION_IMAGE_CAPTURE拍照,返回值为Bitmap图片
  • TakePicture:调用MediaStore.ACTION_IMAGE_CAPTURE拍照,并将图片保存到给定的Uri地址,返回true表示保存成功。
  • TakeVideo: 调用MediaStore.ACTION_VIDEO_CAPTURE 拍摄视频,保存到给定的Uri地址,返回一张缩略图。
  • PickContact:从通讯录APP获取联系人
  • GetContent:提示用选择一条内容,返回一个通过ContentResolver#openInputStream(Uri)访问原生数据的- Uri地址(content://形式) 。默认情况下,它增加了Intent#CATEGORY_OPENABLE, 返回可以表示流的内容。
  • CreateDocument:提示用户选择一个文档,返回一个(file:/http:/content:)开头的Uri。
  • OpenMultipleDocuments: 提示用户选择文档(可以选择多个),分别返回它们的Uri,以List的形式。
  • OpenDocumentTree: 提示用户选择一个目录,并返回用户选择的作为一个Uri返回,应用程序可以完全管理返回目录中的文档。
四、如何使用预定的Contract
  • StartActivityForResult的使用,注意返回值定义为ActivityResult。在目标页面的处理同上
 ActivityResultLauncher mylauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
    @Override
    public void onActivityResult(ActivityResult result) {

        Toast.makeText(ResultActivity.this, result.getData().getStringExtra("two_back")+"-----", Toast.LENGTH_SHORT).show();
    }
});

 //  跳转方法
 Intent intent = new Intent(ResultActivity.this, ResultBackTwoActivity.class);
 intent.putExtra("text_string","这里是第二个跳转");
 mylauncher.launch(intent);
  • 单个权限请求(RequestPermission)和多个权限请求(RequestMultiplePermissions)的使用
//  初始化单个权限请求
ActivityResultLauncher requestpermiss = registerForActivityResult(new ActivityResultContracts.RequestPermission(), new ActivityResultCallback<Boolean>() {
    @Override
    public void onActivityResult(Boolean result) {
        Toast.makeText(ResultActivity.this, "获取权限"+result, Toast.LENGTH_SHORT).show();
    }
});

//  初始化多个权限请求
ActivityResultLauncher requestpermissgroup = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
    @Override
    public void onActivityResult(Map<String, Boolean> result) {
        Set entries = result.entrySet( );
        if(entries != null) {
            Iterator iterator = entries.iterator( );
            while(iterator.hasNext( )) {
                Map.Entry entry = (Map.Entry) iterator.next( );
                Object key = entry.getKey( );
                Object value = entry.getValue();
                Toast.makeText(ResultActivity.this, key+"权限获取"+value, Toast.LENGTH_SHORT).show();
            }
        }
    }
});

//    单个权限请求实现
requestpermiss.launch(Manifest.permission.BLUETOOTH);

//    多个权限请求实现
String[] permissgroup = new String[]{
                    Manifest.permission.BLUETOOTH,
                    Manifest.permission.NFC,
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.CAMERA};
 requestpermissgroup.launch(permissgroup);
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容