学习进度条64
使用方式
1. 使用下面的一种方式去获取需要的权限
PermissionGen.with(MainActivity.this)
.addRequestCode(100)
.permissions(
Manifest.permission.READ_CONTACTS,
Manifest.permission.RECEIVE_SMS,
Manifest.permission.WRITE_CONTACTS)
.request();
or
PermissionGen.needPermission(ContactFragment.this, 100,
new String[] {
Manifest.permission.READ_CONTACTS,
Manifest.permission.RECEIVE_SMS,
Manifest.permission.WRITE_CONTACTS
}
);
2.重写 onRequestPermissionsResult 方法
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
PermissionGen.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
3.回调
正确:
@PermissionSuccess(requestCode = 100)
public void doSomething(){
Toast.makeText(this, "Contact permission is granted", Toast.LENGTH_SHORT).show();
}
错误:
@PermissionFail(requestCode = 100)
public void doFailSomething(){
Toast.makeText(this, "Contact permission is not granted", t.LENGTH_SHORT).show();
}
往往一个框架,简单的使用方式,背后大多数是非常复杂的架构或者设计模式,这个架构的代码量以及难度不是非常大,配合源码食用更佳。
基本分析
成员变量
//保存需要的权限
private String[] mPermissions;
//请求码
private int mRequestCode;
//保存Activity or Fragment
private Object object;
构造方法
//私有化了构造方法
private PermissionGen(Object object) {
this.object = object;
}
with方法
很多开源库惯用的手法,既传入Activity or Fragment的方法,并且调用构造方法,我想这个大家应该不能理解。
public static PermissionGen with(Activity activity){
return new PermissionGen(activity);
}
public static PermissionGen with(Fragment fragment){
return new PermissionGen(fragment);
}
赋值
既然有了对象,接下来就是对对象的成员变量进行赋值了。
//当然还有另外一种方式去添加 permissions 就是 needPermission 留个大家自己去思考咯
public PermissionGen permissions(String... permissions){
this.mPermissions = permissions;
return this;
}
public PermissionGen addRequestCode(int requestCode){
this.mRequestCode = requestCode;
return this;
}
上述几个流程是非常简单的,如果你经常拆轮子,对于这些手法已经见怪不怪了,接下来就说说他是如果通过注解反射来进行权限申请已经回调的吧。
核心分析
requestResult
在使用方式的第二步调用了 PermissionGen.onRequestPermissionsResult(this, requestCode, permissions, grantResults); ,这是一个重载的方法,主要是第一个参数会不同,this可以是指向的对象可以是Fragment or Activity,但是最终都回调到一个方法。
public static void onRequestPermissionsResult(Activity activity, int requestCode, String[] permissions,int[] grantResults) {
requestResult(activity, requestCode, permissions, grantResults);
}
public static void onRequestPermissionsResult(Fragment fragment, int requestCode, String[] permissions,int[] grantResults) {
requestResult(fragment, requestCode, permissions, grantResults);
}
最终都调用以下方法:
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);
}
}
使用注解的方式回调
正确时的回调的放阿飞
private static void doExecuteFail(Object activity, int requestCode) {
//方法一
Method executeMethod = Utils.findMethodWithRequestCode(activity.getClass(),PermissionFail.class, requestCode);
//方法二
executeMethod(activity, executeMethod);
}
方法一:
public static <A extends Annotation> Method findMethodWithRequestCode(Class clazz,Class<A> annotation, int requestCode) {
//循环这个对象中的方法
for(Method method : clazz.getDeclaredMethods()){
//判断每个方法的注解是不是符合 annotation(PermissionSuccess or PermissionFail)
if(method.isAnnotationPresent(annotation)){
//最后调用了这个方法,就不copy了,非常简单,判断他的 requestCode
if(isEqualRequestCodeFromAnntation(method, annotation, requestCode)){
return method;
}
}
}
return null;
}
方法二:
通过反射我们拿到了需要的方法,接下来就是运行这个方法了
private static void executeMethod(Object activity, Method executeMethod) {
if(executeMethod != null){
try {
if(!executeMethod.isAccessible()) executeMethod.setAccessible(true);
//运行这个方法
executeMethod.invoke(activity, null);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
是不是非常简单,简单明了的几步流程,然后我们再睡觉描一眼 PermisstionSuccess 与 PermisstionFail 两个类
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PermissionFail {
int requestCode();
}
与
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PermissionSuccess {
int requestCode();
}