zoukankan      html  css  js  c++  java
  • 学习进度条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();

    }

  • 相关阅读:
    Object.assign () 和深拷贝
    在关机或重启前,关闭有道云笔记
    OpenSSL生成加密证书.cer和.pfx
    scrcpy 安卓投屏
    C#.NET AES CBC 加密
    华擎B365M ITX ,SSD WIN7 电脑卡顿,4K异常,9代 I7
    华擎B365 BIOS 设置来电启动,来电自启,来电后开机
    打开 gpedit.msc 组策略时弹出错误提示,"找不到资源 string.Advanced_EnableSSL3Fallback ”。
    将手机声音通过蓝牙输入到WIN10电脑
    CSS选择器——cssSelector定位方式详解
  • 原文地址:https://www.cnblogs.com/hhw12345/p/14910557.html
Copyright © 2011-2022 走看看