学习进度条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();

}

原文地址:https://www.cnblogs.com/hhw12345/p/14910557.html