RxPermissions 源码分析

  1. 内部初始化一个 RxPermissionsFragment

    RxPermissionsFragment mRxPermissionsFragment;
    
        public RxPermissions(@NonNull Activity activity) {
            mRxPermissionsFragment = getRxPermissionsFragment(activity);
        }
    
        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);
        }
    
        public void setLogging(boolean logging) {
            mRxPermissionsFragment.setLogging(logging);
        }
  2. 单一权限请求

    /**
     * 单个权限
     *
     * @param permissions
     * @return
     */
    @SuppressWarnings("WeakerAccess")
    public Observable.Transformer<Object, Permission> ensureEach(final String... permissions) {
        return new Observable.Transformer<Object, Permission>() {
            @Override
            public Observable<Permission> call(Observable<Object> o) {
                return request(o, permissions);
            }
        };
    }
    
  3. 多个权限请求

        /**
         * 多个权限请求
         *
         * @param permissions
         * @return
         */
        @SuppressWarnings("WeakerAccess")
        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) //它定期从Observable收集数据到一个集合,然后把这些数据集合打包发 射,而不是一次发射一个
                            .flatMap(new Func1<List<Permission>, Observable<Boolean>>() {
                                @Override
                                public Observable<Boolean> call(List<Permission> permissionList) {
                                    if (permissionList.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 permissionList are granted.
                                    for (Permission p : permissionList) {
                                        if (!p.granted) {
                                            return Observable.just(false);
                                        }
                                    }
                                    return Observable.just(true);
                                }
                            });
                }
            };
        }
    
  4. 发起权限请求

    /**
         * 权限请求
         *
         * @param trigger
         * @param permissions
         * @return
         */
        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");
            }
            /*Observable<?> observable = oneOf(trigger, pending(permissions));
            observable.flatMap(new Func1<Object, Observable<?>>() {
                @Override
                public Observable<?> call(Object o) {
                    return null;
                }
            })*/
            return oneOf(trigger, pending(permissions))
                    .flatMap(new Func1<Object, Observable<Permission>>() {
                        @Override
                        public Observable<Permission> call(Object o) {
                            // 处理权限请求
                            return requestImplementation(permissions);
                        }
                    });
        }
    
        /**
         * 权限请求
         *
         * @param permissions 请求的权限 ,一般一个
         * @return
         */
        @TargetApi(Build.VERSION_CODES.M)
        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) {
                if (isGranted(permission)) {//允许
                    // Already granted, or not Android M
                    // Return a granted Permission object.
                    list.add(Observable.just(new Permission(permission, true, false)));
                    continue;
                }
    
                if (isRevoked(permission)) {//拒绝
                    // Revoked by a policy, return a denied Permission object.
                    list.add(Observable.just(new Permission(permission, false, false)));
                    continue;
                }
    
                // 系统未处理过的权限
                PublishSubject<Permission> subject = rxPermissionFragment.getSubjectByPermission(permission);
                // Create a new subject if not exists
                if (subject == null) {
                    unrequestedPermissions.add(permission);
                    subject = PublishSubject.create();
                    rxPermissionFragment.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)//多个Observable
                    );// 不交错的连接多个Observable的数据
        }
    
  5. RxPermissionsFragment 内部封装的空Fragment

    ```
    @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setRetainInstance(true);
        }
     1. setRetainInstance(true):
        如果想叫自己的Fragment即使在其Activity重做时也不进行销毁那么就要设置setRetainInstance(true)。进行了这样的操作后,一旦发生Activity重组现象,Fragment会跳过onDestroy直接进行onDetach(界面消失、对象还在),而Framgnet重组时候也会跳过onCreate,而onAttach和onActivityCreated还是会被调用。需要注意的是,要使用这种操作的Fragment不能加入backstack后退栈中。并且,被保存的Fragment实例不会保持太久,若长时间没有容器承载它,也会被系统回收掉的。
    
        /**
         * 权限请求
         * @param permissions
         */
        @TargetApi(Build.VERSION_CODES.M)
        void requestPermissions(@NonNull String[] permissions) {
            requestPermissions(permissions, PERMISSIONS_REQUEST_CODE);
        }
    
    // 权限响应回调
    @TargetApi(Build.VERSION_CODES.M)
        public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            // 非本次请求的 响应吗
            if (requestCode != PERMISSIONS_REQUEST_CODE) return;
    
            // 判断权限是否被用户拒绝过
            boolean[] shouldShowRequestPermissionRationale = new boolean[permissions.length];
            for (int i = 0; i < permissions.length; i++) {
                shouldShowRequestPermissionRationale[i] = shouldShowRequestPermissionRationale(permissions[i]);
            }
    
            onRequestPermissionsResult(permissions, grantResults, shouldShowRequestPermissionRationale);
        }
    
    2. shouldShowRequestPermissionRationale(@NonNull String permission) {}
    这个方法是AppCompact里面的,用于权限管理.
    为了帮助查找用户可能需要解释的情形,Android 提供了一个实用程序方法,即 shouldShowRequestPermissionRationale()。如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。
    
    注:如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don’t ask again 选项,此方法将返回 false。如果设备规范禁止应用具有该权限,此方法也会返回 false
    
    void checkPermissions() {  
            if (ContextCompat.checkSelfPermission(this,  
                    Manifest.permission.READ_CONTACTS)  
                    != PackageManager.PERMISSION_GRANTED) {  
                if (!ActivityCompat.shouldShowRequestPermissionRationale(this,  
                        Manifest.permission.READ_CONTACTS)) {  
                    //第一次全新进入时,shouldShowRequestPermissionRationale方法将返回false,这里将会执行。  
                    //请求权限时如果点了拒绝但是没勾选不再提醒,shouldShowRequestPermissionRationale方法将返回true,这里将不执行。  
                    //点了拒绝且勾选了不再提醒,再次进入时,shouldShowRequestPermissionRationale方法也将返回false,并且权限请求将无任何响应,然后可以在下面方法中做些处理,提示用户打开权限。  
                    ActivityCompat.requestPermissions(this,  
                            new String[]{Manifest.permission.READ_CONTACTS},  
                            1);  
                } else {  
                    ActivityCompat.requestPermissions(this,  
                            new String[]{Manifest.permission.READ_CONTACTS},  
                            1);  
                }  
            }  
        }  
    ```
    
  6. onRequestPermissionsResult() 处理权限

     void onRequestPermissionsResult(String permissions[], int[] grantResults, boolean[] shouldShowRequestPermissionRationale) {
            for (int i = 0, size = permissions.length; i < size; i++) {
    
                // Find the corresponding(相应的) subject
                // PublishSubject只会把在订阅发生的时间点 之后 来自原始Observable的数据发射给观察者。
                PublishSubject<Permission> subject = subjectHashMap.get(permissions[i]);
                if (subject == null) {
                    // No subject found
                    return;
                }
                // subject != null
                // 权限请求完成 将当前 permission 移除
                subjectHashMap.remove(permissions[i]);
                // 权限允许
                boolean granted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
                subject.onNext(new Permission(permissions[i], granted, shouldShowRequestPermissionRationale[i]));
                subject.onCompleted();
            }
        }
    

猜你喜欢

转载自blog.csdn.net/elzza/article/details/78562753