一、感悟
看了源码后,有个感慨,就是以后源码的分析还是自己先看,看不懂再去看人家写的,因为自己看思路把握得更加好,看人家的也更容易看懂。
二、使用
RxPermissions rxPermissionss = new RxPermissions(this);
rxPermissionss.request(Manifest.permission.READ_PHONE_STATE)
.subscribe(new Subscriber<Boolean>(this) {
@Override
public void onNext(Boolean aBoolean) {
if (aBoolean) {
//权限同意后的操作
} else {
//权限拒绝后的操作
}
}
});
三、分析
fragment简称碎片,可以嵌入到Activity中,没想到它还可以这样用
对比:
一般的动态请求权限是
询问-->同意授权/不同意授权-->method-->end
询问-->回调-->同意/不同意授权-->end
RxPermissions
询问-->同意授权/不同意授权-->method-->end
询问-->(fragment回调)-->同意/不同意授权-->end
思路(前提是已经了解了rxjava基础)
可见RxPermissions会直接隐藏掉了回调的步骤,原因就是利用rxjava的观察者模式
1.对于授权或者没有授权的情况,换句话就是已经有结果了的情况,会直接返回带有结果的Observable
2.对于需要询问的情况,记录需要询问的权限,然后调用询问的方法,之后将结果以同样的方式返回Observable
3.有了带结果的Observable,就可以直接根据结果调方法
源码分析
1.为Activity添加fragment
private RxPermissionsFragment getRxPermissionsFragment(Activity activity) {
RxPermissionsFragment rxPermissionsFragment = findRxPermissionsFragment(activity);
boolean isNewInstance = rxPermissionsFragment == null;
if (isNewInstance) {
rxPermissionsFragment = new RxPermissionsFragment();
FragmentManager fragmentManager = activity.getFragmentManager();
fragmentManager
.beginTransaction()
.add(rxPermissionsFragment, TAG)
.commitAllowingStateLoss();
fragmentManager.executePendingTransactions();
}
return rxPermissionsFragment;
}
private RxPermissionsFragment findRxPermissionsFragment(Activity activity) {
return (RxPermissionsFragment) activity.getFragmentManager().findFragmentByTag(TAG);
}
2.将权限传递过来
public Observable<Boolean> request(final String... permissions) {
return Observable.just(null).compose(ensure(permissions));
}
3.看ensure方法
public Observable.Transformer<Object, Boolean> ensure(final String... permissions) {
return new Observable.Transformer<Object, Boolean>() {
@Override
public Observable<Boolean> call(Observable<Object> o) {
return request(o, permissions)
// Transform Observable<Permission> to Observable<Boolean>
.buffer(permissions.length)
.flatMap(new Func1<List<Permission>, Observable<Boolean>>() {
@Override
public Observable<Boolean> call(List<Permission> permissions) {
if (permissions.isEmpty()) {
// Occurs during orientation change, when the subject receives onComplete.
// In that case we don't want to propagate that empty list to the
// subscriber, only the onComplete.
return Observable.empty();
}
// Return true if all permissions are granted.
for (Permission p : permissions) {
if (!p.granted) {
return Observable.just(false);
}
}
return Observable.just(true);
}
});
}
};
}
首先关注flatMap操作符后的操作,最后返回权限的集合,遍历集合,通过封装权限类的第二个参数得到是否同意权限,返回布尔值。
再往上看buffer,目的是将所有权限以一个集合返回
再往上看requset操作符,点击进去
private Observable<Permission> request(final Observable<?> trigger, final String... permissions) {
if (permissions == null || permissions.length == 0) {
throw new IllegalArgumentException("RxPermissions.request/requestEach requires at least one input permission");
}
return oneOf(trigger, pending(permissions))
.flatMap(new Func1<Object, Observable<Permission>>() {
@Override
public Observable<Permission> call(Object o) {
return requestImplementation(permissions);
}
});
}
进而看requestImplementation方法
private Observable<Permission> requestImplementation(final String... permissions) {
List<Observable<Permission>> list = new ArrayList<>(permissions.length);
List<String> unrequestedPermissions = new ArrayList<>();
// In case of multiple permissions, we create an Observable for each of them.
// At the end, the observables are combined to have a unique response.
for (String permission : permissions) {
mRxPermissionsFragment.log("Requesting permission " + permission);
if (isGranted(permission)) {
// 同意权限情况
list.add(Observable.just(new Permission(permission, true, false)));
continue;
}
if (isRevoked(permission)) {
// 拒绝权限情况
list.add(Observable.just(new Permission(permission, false, false)));
continue;
}
PublishSubject<Permission> subject = mRxPermissionsFragment.getSubjectByPermission(permission);
// Create a new subject if not exists
if (subject == null) {
//需要询问的权限的添加
unrequestedPermissions.add(permission);
subject = PublishSubject.create();
mRxPermissionsFragment.setSubjectForPermission(permission, subject);
}
list.add(subject);
}
if (!unrequestedPermissions.isEmpty()) {
//需要询问的权限列表
String[] unrequestedPermissionsArray = unrequestedPermissions.toArray(new String[unrequestedPermissions.size()]);
//请求权限询问
requestPermissionsFromFragment(unrequestedPermissionsArray);
}
return Observable.concat(Observable.from(list));
}
可以先看注释,已经有权限请求结果的就不用再次询问了,直接just 发送就好。对于新的权限请求,则需要调用mRxPermissionsFragment中的方法进行询问,询问后onNext()发送出去。
方法的最后返回Observable.concat(Observable.from(list)),是所有的请求有序发出
有关询问的方法,细看mRxPermissionsFragment中的此方法
void onRequestPermissionsResult(String permissions[], int[] grantResults, boolean[] shouldShowRequestPermissionRationale) {
for (int i = 0, size = permissions.length; i < size; i++) {
log("onRequestPermissionsResult " + permissions[i]);
// Find the corresponding subject
PublishSubject<Permission> subject = mSubjects.get(permissions[i]);
if (subject == null) {
// No subject found
Log.e(RxPermissions.TAG, "RxPermissions.onRequestPermissionsResult invoked but didn't find the corresponding permission request.");
return;
}
mSubjects.remove(permissions[i]);
boolean granted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
subject.onNext(new Permission(permissions[i], granted, shouldShowRequestPermissionRationale[i]));
subject.onCompleted();
}
}
完成到这里,就基本上将所有请求全部发出,而且经历多次转换拿到了权限的请求结果,被观察者已经完成任务了,剩下的就交给观察者啦,回看文章开头的使用方法吧
喵印~~