Flow是kotlin协程的一个类似RxJava的流式API,它的出现可以替代RxJava,这里就介绍RxJava之前热门的权限框架RxPermission的替代
1. RxPermission中存在的严重的BUG,
举例如下代码, Camera权限拒绝, READ_PHONE_STATE允许订阅回调值就是true(调试BUG前提两权限都没申请过)
RxPermissions(this).request(Manifest.permission.READ_PHONE_STATE, Manifest.permission.CAMERA)
从RxPermission原码中截取的一部分原码:
@TargetApi(Build.VERSION_CODES.M)
private Observable<Permission> requestImplementation(final String... permissions) {
List<Observable<Permission>> list = new ArrayList<>(permissions.length);
List<String> unrequestedPermissions = new ArrayList<>();
......
return Observable.concat(Observable.fromIterable(list));
}
从最后一行代码可以看出是将List中的多个Observable<Permission>合并成一个,问题也是出在这里,而concat 操作符是接收若干个Observables,而权限请求onRequestPermissionsResult回调却不一定是按请求时的顺序来的才导致这个问题,而如果将concat改成merge时,第一次请求未回调完成前再去请求权限组, 这时就会出现回调多次的情况
如何解决: 权限请求在回调时会一般是触发界面弹窗提示, 而在第一次的请求权限组回调全部完成前, 这时再去请求权限会立刻回调空的数组, 直到第一次请求的权限组回调完成, 所以在第一次请求权限组时将需要返回的权限数据源直接放到到一个Observable中, 多次请求权限时无效返回Empty的Observable
2. FlowPermission 使用协程的Flow流式方式回调权限申请
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.youxiaochen:FlowPermission:1.2.0'
}
lifecycleScope.launch {
flowPermission.requestEach(Manifest.permission.READ_PHONE_STATE, Manifest.permission.CAMERA)
.collect { Log.d("FlowPermission", "collect permission = $it")}
}