一、感悟
看了源碼後,有個感慨,就是以後源碼的分析還是自己先看,看不懂再去看人家寫的,因爲自己看思路把握得更加好,看人家的也更容易看懂。
二、使用
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();
}
}
先寫這麼多,後續再補充
喵印~~