android 权限源码分析,Android RxPermissions源码分析

一、感悟

看了源码后,有个感慨,就是以后源码的分析还是自己先看,看不懂再去看人家写的,因为自己看思路把握得更加好,看人家的也更容易看懂。

二、使用

RxPermissions rxPermissionss = new RxPermissions(this);

rxPermissionss.request(Manifest.permission.READ_PHONE_STATE)

.subscribe(new Subscriber(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 request(final String... permissions) {

return Observable.just(null).compose(ensure(permissions));

}

3.看ensure方法

public Observable.Transformer ensure(final String... permissions) {

return new Observable.Transformer() {

@Override

public Observable call(Observable o) {

return request(o, permissions)

// Transform Observable to Observable

.buffer(permissions.length)

.flatMap(new Func1, Observable>() {

@Override

public Observable call(List 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 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>() {

@Override

public Observable call(Object o) {

return requestImplementation(permissions);

}

});

}

进而看requestImplementation方法

private Observable requestImplementation(final String... permissions) {

List> list = new ArrayList<>(permissions.length);

List 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 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 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();

}

}

完成到这里,就基本上将所有请求全部发出,而且经历多次转换拿到了权限的请求结果,被观察者已经完成任务了,剩下的就交给观察者啦,回看文章开头的使用方法吧

喵印~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值