Android RxPermissions源码分析
2019-04-26 本文已影响10人
蓝库知识
一、感悟
看了源码后,有个感慨,就是以后源码的分析还是自己先看,看不懂再去看人家写的,因为自己看思路把握得更加好,看人家的也更容易看懂。
二、使用
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中,没想到它还可以这样用
对比:
一般的动态请求权限是
1.询问-->回调-->同意授权-->method-->end
2.询问-->回调-->不同意授权-->end
3.询问-->已授权/未授权-->method-->end
RxPermissions
询问-->同意授权-->method-->end
询问-->不同意授权-->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操作符后的操作,就是返回包含权限请求结果的Observable。
再往上看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));
}
可以先看注释,然后注意
mRxPermissionsFragment.setSubjectForPermission(permission, subject);
此方法中注意mRxPermissionsFragment这个类,这个类主要是处理请求权限询问结果的,处理完通过subject发出来
细看此方法
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();
}
}
先写这么多,后续再补充
喵印~~