# AOP **Repository Path**: ghostbullets/AOP ## Basic Information - **Project Name**: AOP - **Description**: 学习 AOP(Android)应用框架 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-03-17 - **Last Updated**: 2021-12-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # XAOP 一个轻量级的AOP(Android)应用框架。囊括了最实用的AOP应用。 [![](https://jitpack.io/v/com.gitee.ghostbullets/AOP.svg)](https://jitpack.io/#com.gitee.ghostbullets/AOP) [![api](https://img.shields.io/badge/API-16+-brightgreen.svg)](https://android-arsenal.com/api?level=16) ## 关于我 [![gitee](https://img.shields.io/badge/gitee-ghostbullets-blue.svg)](https://gitee.com/ghostbullets) [![github](https://img.shields.io/badge/github-ghostbullets-blue.svg)](https://github.com/ghostbullets) [![csdn](https://img.shields.io/badge/CSDN-a2923790861-green.svg)](https://blog.csdn.net/a2923790861) ## 特点 * 支持快速点击切片`@SingleClick`,支持设置快速点击的时间间隔。 * 支持动态申请权限切片`@ApplyPermission`,支持自定义响应动作。 * 支持线程切片`@WorkThread`,支持主线程、多种线程池类型 * 支持日志打印切片`@DebugLog`,支持自定义日志记录方式。 * 支持自动捕获异常的拦截切片`@CaptureThrowable`,支持设置自定义异常处理者。 * 支持自定义拦截切片`@Intercept`,支持自定义切片拦截。 * 兼容Kotlin语法。 ## 1、演示(请star支持) ## 2、如何使用 目前支持主流开发工具AndroidStudio的使用,直接配置build.gradle,增加依赖即可. ### 2.1、Android Studio导入方法,添加Gradle依赖 1.先在项目根目录的 build.gradle 的 repositories 添加: ``` allprojects { repositories { ... maven { url "https://jitpack.io" } } } ``` 2.再在项目根目录的 build.gradle 的 dependencies 添加aop插件: ``` buildscript { ··· dependencies { ··· classpath 'com.gitee.ghostbullets.AOP:aop-plugin:0.0.2-beta' //如果你升级到androidx,请使用下面依赖 classpath 'com.gitee.ghostbullets.AOP:aop-plugin:0.0.2-androidx-beta' } } ``` 3.在项目的 build.gradle 中增加依赖并引用aop插件 ``` apply plugin: 'com.cjf.aop' //引用aop插件 dependencies { ··· //添加依赖 implementation 'com.gitee.ghostbullets.AOP:aop-runtime:0.0.2-beta' //如果你升级到androidx,请使用下面依赖 implementation 'com.gitee.ghostbullets.AOP:aop-runtime:0.0.2-androidx-beta' } ``` 4.在Application中进行初始化 ``` AOPManager.init(this); //初始化插件 AOPManager.debug(true); //日志打印切片开启 AOPManager.setPriority(Log.INFO); //设置日志打印的等级,默认为0 //在Application里,设置动态申请权限切片 申请权限被拒绝的事件响应监听 AOPManager.setOnPermissionDeniedListener(new PermissionUtils.OnPermissionDeniedListener() { @Override public void onDenied(List permissionsDeniedForever, List permissionsDenied, List permissionsGranted) { XLogger.e("申请权限拒绝情况: \n 拒绝列表:{ " + Utils.listToString(permissionsDenied) + "} \n 拒绝并不在询问列表:{" + Utils.listToString(permissionsDeniedForever) + "} \n 同意授权列表:{" + Utils.listToString(permissionsGranted) + "}"); } }); //在Activity里,设置局部事件响应监听 AOPManager.addLocalOnPermissionDeniedListener(new PermissionUtils.OnPermissionDeniedListener() { @Override public void onDenied(List permissionsDeniedForever, List permissionsDenied, List permissionsGranted) { XLogger.e("申请权限被拒绝局部拦截"); } }); //设置自定义拦截切片的处理拦截器 AOPManager.setInterceptor(new Interceptor() { @Override public boolean intercept(int type, ProceedingJoinPoint joinPoint) throws Throwable { XLogger.d("正在进行拦截,拦截类型:" + type); switch(type) { case 1: //做你想要的拦截 break; case 2: return true; //return true,直接拦截切片的执行 default: break; } return false; } }); //设置自动捕获异常的处理者 AOP.setThrowableHandler(new IThrowableHandler() { @Override public Object handleThrowable(String flag, Throwable throwable) { XLogger.d("捕获到异常,异常的flag:" + flag); if (flag.equals(TRY_CATCH_KEY)) { return 100; } return null; } }); ``` ### 2.2、兼容Kotlin语法配置 1.在项目根目录的 build.gradle 的 dependencies 添加aspectjx插件: ``` buildscript { ··· dependencies { ··· classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.8' } } ``` 2.在项目的 build.gradle 中增加依赖并引用aspectjx插件 ``` apply plugin: 'android-aspectjx' //引用aspectjx插件 ``` 详细使用可参见app项目进行使用. ## 3、切片的使用 ### 3.1、快速点击切片使用 1.使用`@SingleClick`标注点击的方法。注意点击的方法中一定要有点击控件View作为方法参数,否则将不起作用。 2.可以设置快速点击的时间间隔,单位:ms。不设置的话默认是1000ms。 ``` @SingleClick @DebugLog(priority = Log.ERROR) public void handleOnClick(View v) { XLogger.e("点击响应!"); //Toast.makeText(MainActivity.this, "你点击了", Toast.LENGTH_SHORT).show(); } ``` ### 3.2、动态申请权限切片使用 1.使用`@ApplyPermission`标注需要申请权限执行的方法。可设置申请一个或多个权限。 2.使用`@ApplyPermission`标注的方法,在执行时会自动判断是否需要申请权限。 ``` @ApplyPermission({Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.READ_PHONE_STATE,Manifest.permission.RECORD_AUDIO}) public void handleRequestPermission(View view) { Toast.makeText(AOPManager.getContext(), "权限已申请", Toast.LENGTH_SHORT).show(); } ``` ### 3.3、线程切片使用 1.使用`@WorkThread`标注需要在主线程或者子线程中执行的方法。可设置线程池的类型`ThreadType`,不设置的话默认是Main类型。 2.使用`@WorkThread`标注的方法,在执行时会自动切换至指定类型的线程 3.线程池的类型如下: * Single:单线程池 * Fixed:多线程池 * Disk:磁盘读写线程池(本质上是单线程池) * Network:网络请求线程池(本质上是多线程池) ``` AppExecutors.get().poolIO().execute(new Runnable() { @Override public void run() { String s = doInMainThread(v); XLogger.e("子线程内打印主线程返回结果:" + s); } }); @WorkThread(ThreadType.MAIN) private String doInMainThread(View v) { mTvHello.setText("工作在主线程"); return "工作在主线程"; } @WorkThread(ThreadType.IO_Single) private String doInIOThread(View v) { return "io线程名:" + Thread.currentThread().getName(); } ``` ### 3.4、日志打印切片使用 1.使用`@DebugLog`标注需要打印的方法和类。可设置打印的优先级,不设置的话默认优先级为0。注意:如果打印的优先级比`AOPManager.setPriority`设置的优先级小的话,将不会进行打印。 2.使用`@DebugLog`标注的类和方法在执行的过程中,方法名、参数、执行的时间以及结果都将会被打印。 3.可调用`AOPManager.setISerializer`设置打印时序列化参数对象的序列化器。 4.可调用`AOPManager.setLogger`设置打印的实现接口。默认提供的是突破4000限制的logcat日志打印。 ``` @DebugLog(priority = Log.ERROR) private String hello(String name, String cardId) { return "hello, " + name + "! Your CardId is " + cardId + "."; } ``` ### 3.5、自动捕获异常切片使用 1.使用`@CaptureThrowable`标注需要进行异常捕获的方法。可设置一个异常捕获的标志Flag,默认的Flag为当前`类名.方法名`。 2.调用`AOPManager.setThrowableHandler`设置捕获异常的自定义处理者,可实现对异常的弥补处理。如果不设置的话,将只打印异常的堆栈信息。 3.使用`@CaptureThrowable`标注的方法,可自动进行异常捕获,并统一进行异常处理,保证方法平稳执行。 ``` @CaptureThrowable(TRY_CATCH_KEY) private int getNumber() { return 100 / 0; } ``` ### 3.6、自定义拦截切片使用 1.使用`@Intercept`标注需要进行拦截的方法和类。可设置申请一个或多个拦截类型。 2.如果不调用`AOPManager.setInterceptor`设置切片拦截的拦截器的话,自定义拦截切片将不起作用。 3.使用`@Intercept`标注的类和方法,在执行时将自动调用`AOPManager`设置的拦截器进行拦截处理。如果拦截器处理返回true的话,该类或方法的执行将被拦截,不执行。 4.使用`@Intercept`可以灵活地进行切片拦截。比如用户登录权限等。 ``` @Intercept(MyApplication.INTERCEPT_LOGIN) private void doSomeThing() { XLogger.e("已经登录了!"); } @DebugLog(priority = Log.ERROR) @Intercept({1,2,3}) private String hello(String name, String cardId) { return "hello, " + name + "! Your CardId is " + cardId + "."; } ``` 【注意】:当有多个切片注解修饰时,一般是从上至下依次顺序执行。 ## 4、混淆配置 ``` -keep @com.cjf.aop.annotation.* class * {*;} -keep class * { @com.cjf.aop.annotation.* ; } -keepclassmembers class * { @com.cjf.aop.annotation.* ; } ```