MPermission简单分析
一:基本概念
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