MPermission简单分析

2016-09-20  本文已影响1022人  shuixingge

一:基本概念

MPermission: 是针对Android 6.0运行时权限的一个封装库。采用了编译时注解来执行申请权限后的相应回调方法。

二:主要流程

**MPermission.requestPermissions(): ** 用于申请权限,会调用_requestPermissions

public static void requestPermissions(Activity object, int requestCode, String... permissions)
 {  
       _requestPermissions(object, requestCode, permissions);
 }

**MPermission. _requestPermissions() : ** 用于找到那些尚未获得授权的权限。并且根据是当前Activtity还是Fragement调用相应的requestPermissions()来向系统申请权限。

 @TargetApi(value = Build.VERSION_CODES.M)
    private static void _requestPermissions(Object object, int requestCode, String... permissions)
    {
      //如果系统的API小于6.0,那么不需要申请权限。相当于直接获取权限成功。
        if (!Utils.isOverMarshmallow())
        {
      // 表示授权成功,找到相应Activity$$PermissionProxy, 
     //  执行相应辅助代码的grant()方法,在grant()中调用Activity中自定义的带有注解的方法。
            doExecuteSuccess(object, requestCode);
            return;
        }
     //排除掉已经获得授权的权限。
        List<String> deniedPermissions = Utils.findDeniedPermissions(Utils.getActivity(object), permissions);

        if (deniedPermissions.size() > 0)
        {   //申请权限。
            if (object instanceof Activity)
            {
                ((Activity) object).requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
            } else if (object instanceof Fragment)
            {
                ((Fragment) object).requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
            } else
            {
                throw new IllegalArgumentException(object.getClass().getName() + " is not supported!");
            }
        } else
        {   //所有权限都已经授权
            doExecuteSuccess(object, requestCode);
        }
    }

**MPermission. requestResult() : ** 申请权限后的回调方法。

private static void requestResult(Object obj, int requestCode, String[] permissions,
                                      int[] grantResults)
    {
        List<String> deniedPermissions = new ArrayList<>();
        for (int i = 0; i < grantResults.length; i++)
        {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED)
            {
                deniedPermissions.add(permissions[i]);
            }
        }
        if (deniedPermissions.size() > 0)
        {  
           //申请失败
            doExecuteFail(obj, requestCode);
        } else
        {
           //申请成功
            doExecuteSuccess(obj, requestCode);
        }
    }

MPermission.doExecuteSuccess()->MPermission.findPermissionProxy()
->MainActivity$$PermissionProxy.grant().
而MainActivity$$PermissionProxy是通过编译时注解生成的.

三:编译时注解生成代码MainActivity$$PermissionProxy

概念: 编译时注解主要继承通过AbstractProcessor, 一般需要重写如下几个方法。
(1)init():用于初始化一些辅助类,Elements(和元素相关的辅助类, Messager(和日志相关的辅助类)。
(2) getSupportAnnotionTypes():获取支持的注解类型。
(3)getSupportSourceCode():获取到支持的源码版本
(4)process():搜集注解信息,生成相应的注解信息的包装类ProxyInfo,然后根据ProxyInfo生成MainActivity$$PermissionProxy。
Element的种类
(1)VariableElement //一般代表成员变量
(2)ExecutableElement //一般代表类中的方法
(3)TypeElement //一般代表代表类
(4)PackageElement //一般代表Package

上一篇下一篇

猜你喜欢

热点阅读