近期在构建新项目的时候,发现onActivityResult方法已经被废弃了,于是有了尝试registerForActivityResult的想法。
标准使用
三个类ActivityResultLauncher、ActivityResultContract、ActivityResultCallback
首先ActivityResultLauncher作为主角,它需要配置一个泛型,这个泛型跟我们ActivityResultContract的返回值相同,ActivityResultLauncher通过launch方法来启动相应的界面或者功能。
- ActivityResultContract
1 | public static class GalleryContract extends ActivityResultContract<Void, Uri> { |
可以看到ActivityResultContract需要传入两个泛型,一个泛型作为createIntent方法的第二参数类型,这里可以作为我们intent传值的参数载体,ActivityResultContract的另一个泛型作为parseResult方法的返回值类型,我们可以自行定义从intent返回的参数类型。
- ActivityResultLauncher
1 | private ActivityResultLauncher<Void> galleryLauncher = registerForActivityResult(new GalleryContract(), new ActivityResultCallback<Uri>() { |
把contract和ActivityResultCallback作为launcher的参数构建出launcher
- ActivityResultCallback
这个里面就和onActivityResult方法回调一样的,只不过提供的结果参数是我们在contract中定义的。
4.启动launch
通过 galleryLauncher.launch(null);启动即可。
简单使用
ActivityResultContracts
这个类中提供了许多通用的方法
| ActivityResultContracts.* | 说明 | 参数 | 回调 |
|---|---|---|---|
| StartActivityForResult | 可以理解为startActivityForResult | Intent | ActivityResult(code,data) |
| TakePicture | 通过MediaStore.ACTION_IMAGE_CAPTURE拍照并保存 | 保存文件的Uri | 是否保存成功 |
| TakePicturePreview | 通过MediaStore.ACTION_IMAGE_CAPTURE拍照,但是只会拍一张小照片,作为thumbnail使用比较合适 | null(Void) | 图片的Bitmap |
| CaptureVideo | 通过MediaStore.ACTION_VIDEO_CAPTURE拍摄视频并保存(androidx.activity 1.3.0-alpha08后提供,androidx.appcompat好像还没提供该类) | 保存文件的Uri | 是否保存成功。 |
| RequestPermission | 请求单个权限 | Manifest.permission.* | 用户是否授予该权限 |
| RequestMultiplePermissions | 请求多个权限 | Array | 回调为map, key为请求的权限,value为用户是否授予该权限 |
| CreateDocument | 通过Intent.ACTION_CREATE_DOCUMENT创建一个文件 | 默认文件名 | 选择目录后返回该文件的Uri |
| GetContent | 通过Intent.ACTION_GET_CONTENT获取一个文件(这个方法可以通过android.content.ContentResolver.openInputStream获取到文件的原始数据) | MIME类型 | 文件Uri |
| GetMultipleContents | 通过Intent.ACTION_GET_CONTENT及Intent.EXTRA_ALLOW_MULTIPLE获取一个或多个文件(这个方法可以通过android.content.ContentResolver.openInputStream获取到文件的原始数据) | MIME类型 | 文件List |
| OpenDocument | 通过Intent.ACTION_OPEN_DOCUMENT选择文件 | MIME类型 | 文件Uri |
| OpenDocumentTree | 通过Intent.ACTION_OPEN_DOCUMENT_TREE选择一个目录,返回一个Uri并得到该目录下全部文档的管理权 | 目录初始位置Uri | 选择目录Uri |
| OpenMultipleDocuments | 通过Intent.ACTION_OPEN_DOCUMENT及Intent.EXTRA_ALLOW_MULTIPLE获取一个或多个文件 | MIME类型 | 文件List |
| PickContact | 通过Intent.ACTION_PICK从系统通讯录中获取联系人 | null(Void) | 联系人Uri |
| StartIntentSenderForResult* | 构建IntentSender或PendingIntent | 使用IntentSenderRequest.Builder构建 | ActivityResult(code,data) |
| 通过MediaStore.ACTION_VIDEO_CAPTURE拍摄视频并保存(弃用了,官方解释是缩略图的Bitmap的返回不稳定,替换为上面的CaptureVideo即可) | 保存文件的Uri | 视频缩略图Bitmap |
类似的使用如下
1 | private ActivityResultLauncher<String> fileLauncher = registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() { |
1 | private ActivityResultLauncher<Uri> videoLauncher = registerForActivityResult(new ActivityResultContracts.CaptureVideo(), new ActivityResultCallback<Boolean>() { |
注意
不能在需要使用的时候再去构建我们需要的launcher,否则会抛出异常
在Activity中
在Fragment中