{"id":14979955,"url":"https://github.com/xuexiangjys/xaop","last_synced_at":"2025-04-04T11:16:04.716Z","repository":{"id":41300849,"uuid":"130574378","full_name":"xuexiangjys/XAOP","owner":"xuexiangjys","description":"🔥A lightweight AOP(Android) application framework. Includes the most practical AOP applications.(一个轻量级的AOP(Android)应用框架。囊括了最实用的AOP应用)","archived":false,"fork":false,"pushed_at":"2023-12-15T02:40:57.000Z","size":1613,"stargazers_count":734,"open_issues_count":8,"forks_count":97,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-04T11:15:46.372Z","etag":null,"topics":["android","aop","gradle","gradle-aspectjx","kotlin","x-library","xaop"],"latest_commit_sha":null,"homepage":"https://xuexiangjys.github.io/XAOP/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xuexiangjys.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"custom":"https://github.com/xuexiangjys/Resource/blob/master/doc/sponsor.md"}},"created_at":"2018-04-22T14:18:39.000Z","updated_at":"2025-03-19T10:46:16.000Z","dependencies_parsed_at":"2024-01-19T16:09:09.868Z","dependency_job_id":"6aafd508-6d4d-4add-b8ff-80160c78be8d","html_url":"https://github.com/xuexiangjys/XAOP","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xuexiangjys%2FXAOP","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xuexiangjys%2FXAOP/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xuexiangjys%2FXAOP/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xuexiangjys%2FXAOP/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xuexiangjys","download_url":"https://codeload.github.com/xuexiangjys/XAOP/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247166169,"owners_count":20894654,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","aop","gradle","gradle-aspectjx","kotlin","x-library","xaop"],"created_at":"2024-09-24T14:01:00.087Z","updated_at":"2025-04-04T11:16:04.695Z","avatar_url":"https://github.com/xuexiangjys.png","language":"Java","funding_links":["https://github.com/xuexiangjys/Resource/blob/master/doc/sponsor.md"],"categories":[],"sub_categories":[],"readme":"# XAOP\n\n[![](https://jitpack.io/v/xuexiangjys/XAOP.svg)](https://jitpack.io/#xuexiangjys/XAOP)\n[![api](https://img.shields.io/badge/API-14+-brightgreen.svg)](https://android-arsenal.com/api?level=14)\n[![Issue](https://img.shields.io/github/issues/xuexiangjys/XAOP.svg)](https://github.com/xuexiangjys/XAOP/issues)\n[![Star](https://img.shields.io/github/stars/xuexiangjys/XAOP.svg)](https://github.com/xuexiangjys/XAOP)\n\n一个轻量级的AOP(Android)应用框架, 囊括了最实用的AOP应用。心动不如行动，还不赶紧点击[使用说明文档](https://github.com/xuexiangjys/XAOP/wiki)，体验一下吧！\n\n## 关于我\n\n| 公众号   | 掘金     |  知乎    |  CSDN   |   简书   |   思否  |   哔哩哔哩  |   今日头条\n|---------|---------|--------- |---------|---------|---------|---------|---------|\n| [我的Android开源之旅](https://t.1yb.co/Irse)  |  [点我](https://juejin.im/user/598feef55188257d592e56ed/posts)    |   [点我](https://www.zhihu.com/people/xuexiangjys/posts)       |   [点我](https://xuexiangjys.blog.csdn.net/)  |   [点我](https://www.jianshu.com/u/6bf605575337)  |   [点我](https://segmentfault.com/u/xuexiangjys)  |   [点我](https://space.bilibili.com/483850585)  |   [点我](https://img.rruu.net/image/5ff34ff7b02dd)\n\n## X系列库快速集成\n\n为了方便大家快速集成X系列框架库，我提供了一个空壳模版供大家参考使用: https://github.com/xuexiangjys/TemplateAppProject\n\n---\n\n## 特点\n\n* 支持快速点击切片`@SingleClick`，支持设置快速点击的时间间隔。\n\n* 支持动态申请权限切片`@Permission`，支持自定义响应动作。\n\n* 支持主线程切片`@MainThread`。\n\n* 支持IO线程切片`@IOThread`，支持多种线程池类型。\n\n* 支持日志打印切片`@DebugLog`，支持自定义日志记录方式。\n\n* 支持内存缓存切片`@MemoryCache`，支持设置缓存大小。\n\n* 支持磁盘缓存切片`@DiskCache`，支持自定义磁盘缓存，缓存有效时间等。\n\n* 支持自动捕获异常的拦截切片`@Safe`，支持设置自定义异常处理者。\n\n* 支持自定义拦截切片`@Intercept`，支持自定义切片拦截。\n\n* 兼容Kotlin语法。\n\n* 支持androidx。\n\n## Star趋势图\n\n[![Stargazers over time](https://starchart.cc/xuexiangjys/XAOP.svg)](https://starchart.cc/xuexiangjys/XAOP)\n\n---\n\n## 1、演示（请star支持）\n\n![aop.gif](./img/aop.gif)\n\n## 2、如何使用\n目前支持主流开发工具AndroidStudio的使用，直接配置build.gradle，增加依赖即可.\n\n### 2.1、Android Studio导入方法，添加Gradle依赖\n\n1.先在项目根目录的 `build.gradle` 的 repositories 添加:\n```\nallprojects {\n    repositories {\n        ...\n        maven { url \"https://jitpack.io\" }\n    }\n}\n```\n\n2.再在项目根目录的 `build.gradle` 的 dependencies 添加xaop插件：\n\n```\nbuildscript {\n    ···\n    dependencies {\n        ···\n        classpath 'com.github.xuexiangjys.XAOP:xaop-plugin:1.1.0'\n    }\n}\n```\n\n3.在应用项目(一般是app)的 `build.gradle` 中增加依赖并引用xaop插件\n\n```\napply plugin: 'com.xuexiang.xaop' //引用xaop插件\n\ndependencies {\n    ···\n    //如果是androidx项目，使用1.1.0版本及以上\n    implementation 'com.github.xuexiangjys.XAOP:xaop-runtime:1.1.0'\n    //如果是support项目，请使用1.0.5版本\n    implementation 'com.github.xuexiangjys.XAOP:xaop-runtime:1.0.5'\n}\n\n```\n\n4.在Application中进行初始化\n\n```\n\nXAOP.init(this); //初始化插件\nXAOP.debug(true); //日志打印切片开启\nXAOP.setPriority(Log.INFO); //设置日志打印的等级,默认为0\n\n//设置动态申请权限切片 申请权限被拒绝的事件响应监听\nXAOP.setOnPermissionDeniedListener(new PermissionUtils.OnPermissionDeniedListener() {\n    @Override\n    public void onDenied(List\u003cString\u003e permissionsDenied) {\n        //申请权限被拒绝的处理\n    }\n\n});\n\n//设置自定义拦截切片的处理拦截器\nXAOP.setInterceptor(new Interceptor() {\n    @Override\n    public boolean intercept(int type, JoinPoint joinPoint) throws Throwable {\n        XLogger.d(\"正在进行拦截，拦截类型:\" + type);\n        switch(type) {\n            case 1:\n                //做你想要的拦截\n                break;\n            case 2:\n                return true; //return true，直接拦截切片的执行\n            default:\n                break;\n        }\n        return false;\n    }\n});\n\n//设置自动捕获异常的处理者\nXAOP.setIThrowableHandler(new IThrowableHandler() {\n    @Override\n    public Object handleThrowable(String flag, Throwable throwable) {\n        XLogger.d(\"捕获到异常，异常的flag:\" + flag);\n        if (flag.equals(TRY_CATCH_KEY)) {\n            return 100;\n        }\n        return null;\n    }\n});\n\n```\n\n### 2.2、兼容Kotlin语法配置\n\n1.在项目根目录的 `build.gradle` 的 dependencies 添加 [aspectjx](https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx) 插件：\n\n```\nbuildscript {\n    ···\n    dependencies {\n        ···\n        classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.10'\n    }\n}\n```\n\n2.在应用项目(一般是app)的 `build.gradle` 中增加依赖并引用 [aspectjx](https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx) 插件\n\n```\napply plugin: 'android-aspectjx' //引用aspectjx插件\n\naspectjx {\n    include '项目的applicationId'\n}\n\n```\n\n详细使用可参见[kotlin-test](https://github.com/xuexiangjys/XAOP/blob/master/kotlin-test/build.gradle)项目进行使用.\n\n## 3、切片的使用\n\n### 3.1、快速点击切片使用\n\n1.使用`@SingleClick`标注点击的方法。注意点击的方法中一定要有点击控件View作为方法参数，否则将不起作用。\n\n2.可以设置快速点击的时间间隔，单位:ms。不设置的话默认是1000ms。\n\n```\n@SingleClick(5000)\npublic void handleOnClick(View v) {\n    XLogger.e(\"点击响应！\");\n    ToastUtil.get().toast(\"点击响应！\");\n    hello(\"xuexiangjys\", \"666666\");\n}\n\n```\n\n### 3.2、动态申请权限切片使用\n\n1.使用`@Permission`标注需要申请权限执行的方法。可设置申请一个或多个权限。\n\n2.使用`@Permission`标注的方法，在执行时会自动判断是否需要申请权限。\n\n```\n@SingleClick\n@Permission({PermissionConsts.CALENDAR, PermissionConsts.CAMERA, PermissionConsts.LOCATION})\nprivate void handleRequestPermission(View v) {\n\n}\n```\n\n### 3.3、主线程切片使用\n\n1.使用`@MainThread`标注需要在主线程中执行的方法。\n\n2.使用`@MainThread`标注的方法，在执行时会自动切换至主线程。\n\n```\n@MainThread\nprivate void doInMainThread(View v) {\n    mTvHello.setText(\"工作在主线程\");\n}\n```\n\n### 3.4、IO线程切片使用\n\n1.使用`@IOThread`标注需要在io线程中执行的方法。可设置线程池的类型`ThreadType`，不设置的话默认是Fixed类型。\n\n线程池的类型如下:\n\n* Single:单线程池\n* Fixed:多线程池\n* Disk:磁盘读写线程池(本质上是单线程池）\n* Network:网络请求线程池(本质上是多线程池）\n\n2.使用`@IOThread`标注的方法，在执行时会自动切换至指定类型的io线程。\n\n```\n@IOThread(ThreadType.Single)\nprivate String doInIOThread(View v) {\n    return \"io线程名:\" + Thread.currentThread().getName();\n}\n```\n\n### 3.5、日志打印切片使用\n\n1.使用`@DebugLog`标注需要打印的方法和类。可设置打印的优先级，不设置的话默认优先级为0。注意：如果打印的优先级比`XAOP.setPriority`设置的优先级小的话，将不会进行打印。\n\n2.使用`@DebugLog`标注的类和方法在执行的过程中，方法名、参数、执行的时间以及结果都将会被打印。\n\n3.可调用`XAOP.setISerializer`设置打印时序列化参数对象的序列化器。\n\n4.可调用`XAOP.setLogger`设置打印的实现接口。默认提供的是突破4000限制的logcat日志打印。\n\n```\n@DebugLog(priority = Log.ERROR)\nprivate String hello(String name, String cardId) {\n    return \"hello, \" + name + \"! Your CardId is \" + cardId + \".\";\n}\n```\n\n### 3.6、内存缓存切片使用\n\n1.使用`@MemoryCache`标注需要内存缓存的方法。可设置缓存的key，不设置的话默认key为`方法名(参数1名=参数1值|参数2名=参数2值|...)`,当然你也可以修改key的自动生成规则，你只需要调用`XAOP.setICacheKeyCreator`即可。\n\n2.标注的方法一定要有返回值，否则内存缓存切片将不起作用。\n\n3.使用`@MemoryCache`标注的方法，可自动实现缓存策略。默认使用的内存缓存是`LruCache`。\n\n4.可调用`XAOP.initMemoryCache`设置内存缓存的最大数量。默认是`Runtime.getRuntime().maxMemory() / 1024) / 8`\n\n```\n@MemoryCache\nprivate String hello(String name, String cardId) {\n    return \"hello, \" + name + \"! Your CardId is \" + cardId + \".\";\n}\n\n```\n\n### 3.7、磁盘缓存切片使用\n\n1.使用`@DiskCache`标注需要磁盘缓存的方法。可设置缓存的key，不设置的话默认key为`方法名(参数1名=参数1值|参数2名=参数2值|...)`,当然你也可以修改key的自动生成规则，你只需要调用`XAOP.setICacheKeyCreator`即可。\n\n2.可设置磁盘缓存的有效期，单位:s。不设置的话默认永久有效。\n\n3.标注的方法一定要有返回值，否则磁盘缓存切片将不起作用。\n\n4.使用`@DiskCache`标注的方法，可自动实现缓存策略。默认使用的磁盘缓存是JakeWharton的`DiskLruCache`。\n\n5.可调用`XAOP.initDiskCache`设置磁盘缓存的属性,包括磁盘序列化器`IDiskConverter`，磁盘缓存的根目录，磁盘缓存的最大空间等。\n\n```\n@DiskCache\nprivate String hello(String name, String cardId) {\n    return \"hello, \" + name + \"! Your CardId is \" + cardId + \".\";\n}\n\n```\n\n### 3.8、自动捕获异常切片使用\n\n1.使用`@Safe`标注需要进行异常捕获的方法。可设置一个异常捕获的标志Flag，默认的Flag为当前`类名.方法名`。\n\n2.调用`XAOP.setIThrowableHandler`设置捕获异常的自定义处理者，可实现对异常的弥补处理。如果不设置的话，将只打印异常的堆栈信息。\n\n3.使用`@Safe`标注的方法,可自动进行异常捕获，并统一进行异常处理，保证方法平稳执行。\n\n```\n@Safe(TRY_CATCH_KEY)\nprivate int getNumber() {\n    return 100 / 0;\n}\n```\n\n### 3.9、自定义拦截切片使用\n\n1.使用`@Intercept`标注需要进行拦截的方法和类。可设置申请一个或多个拦截类型。\n\n2.如果不调用`XAOP.setInterceptor`设置切片拦截的拦截器的话，自定义拦截切片将不起作用。\n\n3.使用`@Intercept`标注的类和方法，在执行时将自动调用`XAOP`设置的拦截器进行拦截处理。如果拦截器处理返回true的话，该类或方法的执行将被拦截，不执行。\n\n4.使用`@Intercept`可以灵活地进行切片拦截。比如用户登录权限等。\n\n```\n@SingleClick(5000)\n@DebugLog(priority = Log.ERROR)\n@Intercept(3)\npublic void handleOnClick(View v) {\n    XLogger.e(\"点击响应！\");\n    ToastUtil.get().toast(\"点击响应！\");\n    hello(\"xuexiangjys\", \"666666\");\n}\n\n@DebugLog(priority = Log.ERROR)\n@Intercept({1,2,3})\nprivate String hello(String name, String cardId) {\n    return \"hello, \" + name + \"! Your CardId is \" + cardId + \".\";\n}\n```\n\n【注意】：当有多个切片注解修饰时，一般是从上至下依次顺序执行。\n\n## 4、混淆配置\n\n```\n-keep @com.xuexiang.xaop.annotation.* class * {*;}\n-keep @org.aspectj.lang.annotation.* class * {*;}\n-keep class * {\n    @com.xuexiang.xaop.annotation.* \u003cfields\u003e;\n    @org.aspectj.lang.annotation.* \u003cfields\u003e;\n}\n-keepclassmembers class * {\n    @com.xuexiang.xaop.annotation.* \u003cmethods\u003e;\n    @org.aspectj.lang.annotation.* \u003cmethods\u003e;\n}\n```\n\n---\n\n## 如果觉得项目还不错，可以考虑打赏一波\n\n\u003e 你的打赏是我维护的动力，我将会列出所有打赏人员的清单在下方作为凭证，打赏前请留下打赏项目的备注！\n\n![pay.png](https://raw.githubusercontent.com/xuexiangjys/Resource/master/img/pay/pay.png)\n\n## 联系方式\n\n![](https://s1.ax1x.com/2022/04/27/LbGMJH.jpg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxuexiangjys%2Fxaop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxuexiangjys%2Fxaop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxuexiangjys%2Fxaop/lists"}