Coder Social home page Coder Social logo

flyjingfish / androidaop Goto Github PK

View Code? Open in Web Editor NEW
313.0 5.0 19.0 13.3 MB

🔥🔥🔥AndroidAOP 是专属于 Android 端 Aop 框架,只需一个注解就可以请求权限、切换线程、禁止多点、一次监测所有点击事件、监测生命周期等等,没有使用 AspectJ,也可以定制出属于你的 Aop 代码

License: Apache License 2.0

Kotlin 81.56% Java 18.44%
aop aop-aspectj aop-aspects aops permission permission-android permissions aspectj android kotlin kotlin-android java

androidaop's Introduction

简体中文 | English

AndroidAOP

Maven central GitHub stars GitHub forks GitHub issues GitHub license

AndroidAOP 是专属于 Android 端 Aop 框架,只需一个注解就可以请求权限、切换线程、禁止多点、监测生命周期等等,本库不是基于 AspectJ 实现的 Aop,当然你也可以定制出属于你的 Aop 代码,心动不如行动,赶紧用起来吧

特色功能

1、本库内置了开发中常用的一些切面注解供你使用

2、本库支持让你自己做切面,语法简单易上手

3、本库同步支持 Java 和 Kotlin 代码

4、本库支持切入三方库

5、本库支持切点方法为 Lambda 表达式的情况

6、本库支持切点方法为 suspend 修饰的协程函数

7、本库支持生成所有切点信息Json文件,方便一览所有切点位置在此配置

8、本库支持 debug 快速开发模式,让你打包速度几乎不变在此配置

9、本库是纯静态织入AOP代码

10、本库不是基于 AspectJ 实现的,织入代码量极少,侵入性极低

show

版本限制

最低Gradle版本:7.6👇(支持8.0以上)

show

最低SDK版本:minSdkVersion >= 21

Star趋势图

Stargazers over time


使用步骤

在开始之前可以给项目一个Star吗?非常感谢,你的支持是我唯一的动力。欢迎Star和Issues!

Stargazers over time

一、引入插件,下边两种方式二选一(必须)

方式一:apply 方式(推荐)

1、在 项目根目录build.gradle 里依赖插件

新版本

plugins {
    //必须项 👇 apply 设置为 true 自动为所有module“预”配置debugMode,false则按下边步骤五的方式二
    id "io.github.FlyJingFish.AndroidAop.android-aop" version "1.9.9" apply true
}

或者老版本

buildscript {
    dependencies {
        //必须项 👇
        classpath 'io.github.FlyJingFish.AndroidAop:android-aop-plugin:1.9.9'
    }
}
// 👇加上这句自动为所有module“预”配置debugMode,不加则按下边步骤五的方式二
apply plugin: "android.aop"

2、在 appbuild.gradle 添加

新版本

//必须项 👇
plugins {
    ...
    id 'android.aop'//最好放在最后一行
}

或者老版本

//必须项 👇
apply plugin: 'android.aop' //最好放在最后一行

Caution

⚠️⚠️⚠️id 'android.aop' 这句尽量放在最后一行,尤其是必须在 id 'com.android.application'id 'com.android.library' 的后边

方式二:plugins 方式(不推荐)

直接在 appbuild.gradle 添加

//必须项 👇
plugins {
    ...
    id "io.github.FlyJingFish.AndroidAop.android-aop" version "1.9.9"//最好放在最后一行
}

二、如果你需要自定义切面,并且代码是 Kotlin (非必须)

1、在 项目根目录build.gradle 里依赖插件

plugins {
    //非必须项 👇,如果需要自定义切面,并且使用 android-aop-ksp 这个库的话需要配置 ,下边版本号根据你项目的 Kotlin 版本决定
    id 'com.google.devtools.ksp' version '1.8.0-1.0.9' apply false
}

Kotlin 和 KSP Github 的匹配版本号列表

三、引入依赖库(必须)

plugins {
    //非必须项 👇,如果需要自定义切面,并且使用 android-aop-ksp 这个库的话需要配置 
    id 'com.google.devtools.ksp'
}

dependencies {
    //必须项 👇
    implementation 'io.github.FlyJingFish.AndroidAop:android-aop-core:1.9.9'
    implementation 'io.github.FlyJingFish.AndroidAop:android-aop-annotation:1.9.9'
    
    //必须项 👇如果您项目内已经有了这项不用加也可以
    implementation 'androidx.appcompat:appcompat:1.3.0' // 至少在1.3.0及以上
    
    //非必须项 👇,如果你想自定义切面需要用到,⚠️支持Java和Kotlin代码写的切面
    ksp 'io.github.FlyJingFish.AndroidAop:android-aop-ksp:1.9.9'
    
    //非必须项 👇,如果你想自定义切面需要用到,⚠️只适用于Java代码写的切面
    annotationProcessor 'io.github.FlyJingFish.AndroidAop:android-aop-processor:1.9.9'
    //⚠️上边的 android-aop-ksp 和 android-aop-processor 二选一
}

Tip

提示:ksp 或 annotationProcessor只能扫描当前 module ,在哪个 module 中有自定义切面代码就加在哪个 module,但是自定义的切面代码是全局生效的;必须依赖项可以通过 api 方式只加到公共 module 上

四、在 app 的build.gradle添加 androidAopConfig 配置项(此步为可选配置项)

  • 1、相关开发配置
plugins {
    ...
    id 'android.aop'//最好放在最后一行
}
androidAopConfig {
    // enabled 为 false 切面不再起作用,默认不写为 true
    enabled true 
    // include 不设置默认全部扫描,设置后只扫描设置的包名的代码
    include '你项目的包名','自定义module的包名','自定义module的包名'
    // exclude 是扫描时排除的包
    // 可排除 kotlin 相关,提高速度
    exclude 'kotlin.jvm', 'kotlin.internal','kotlinx.coroutines.internal', 'kotlinx.coroutines.android'
    
    // verifyLeafExtends 是否开启验证叶子继承,默认打开,@AndroidAopMatchClassMethod 和 @AndroidAopCollectMethod 如果没有设置 LEAF_EXTENDS,可以关闭
    verifyLeafExtends true
    //默认关闭,开启在 Build 或 打包后 将会生成切点信息json文件在 app/build/tmp/cutInfo.json
    cutInfoJson false
    //默认开启,设置 false 后会没有增量编译效果 筛选(关键字: AndroidAOP woven info code) build 输出日志可看时间 
    increment true//修改、增加、删除匹配、收集切面的话,就会走全量编译
}
android {
    ...
}

Tip

合理使用 include 和 exclude 可提高编译速度,建议直接使用 include 设置你项目的相关包名(包括 app 和自定义 module 的) @AndroidAopMatchClassMethod 和 @AndroidAopCollectMethod 如果没有设置 LEAF_EXTENDS,就主动设置 verifyLeafExtends 为 false 也可以提速

Caution

⚠️⚠️⚠️设置完了 include 和 exclude 所有切面只在您设置规则之内才有效,麻烦记住自己的设置!另外设置此处之后由于 Android Studio 可能有缓存,建议先 clean 再继续开发

五、开发中可设置代码织入方式(此步为可选配置项,只为在开发过程中提高打包速度)

Stargazers over time

方式一:(推荐)

按照上述步骤一的方式一配置项目,就可以了。这个方式自动为所有的 module 应用 debugMode

方式二:(不推荐)

Tip

💡💡💡这个方式可以只为你加过的 module 应用 debugMode,没加的 module 里边的相关切面不会生效

请按照上述步骤一的方式一配置项目后,手动为所有子 module 模块设置,例如:

plugins {
    ...
    id 'android.aop'//最好放在最后一行,尤其是必须在 `id 'com.android.application'` 或 `id 'com.android.library'` 的后边
}
  • 2、在根目录gradle.properties 添加如下设置
androidAop.debugMode=true //设置为 true 走您项目当前的打包方式 ,false 则为全量打包方式,不写默认false

Caution

⚠️⚠️⚠️请注意设置为 true 时编译速度会变快但部分功能将失效,只会为设置的 module 织入 aop 代码,三方jar包 不会织入代码,因此打正式包时请注意关闭此项配置并clean项目

  • 3、在根目录gradle.properties 添加如下设置
androidAop.debugMode.variantOnlyDebug = true //默认不写这项就是true

Tip

这项不写默认就是true,请注意设置为 true 时 release 包会忽略 androidAop.debugMode = true 的设置自动走全量打包方式,设为 false 时则没有这种效果

此项功能默认开启,因此release包无需手动关闭 androidAop.debugMode

  • 4、在根目录gradle.properties 添加如下设置(选填,追求极致可以配置这项)
androidAop.reflectInvokeMethod = true //设置为 true 反射执行切面方法 ,不写默认 false
androidAop.reflectInvokeMethod.variantOnlyDebug = true // 设置为 true 则只会在 debug 下才有效,不写默认false

Tip

1、反射执行切面方法会加快打包速度
2、请注意androidAop.reflectInvokeMethod.variantOnlyDebug 设置为 true 时 release 包会忽略 androidAop.reflectInvokeMethod = true 的设置自动不走反射,设为 false 时则没有这种效果(不写默认false)
3、在 1.8.7 及其以上的版本上,已优化到二次编译速度和开启反射速度是基本一样的

本库内置了一些功能注解可供你直接使用

注解名称 参数说明 功能说明
@SingleClick value = 快速点击的间隔,默认1000ms 单击注解,加入此注解,可使你的方法只有单击时才可进入
@DoubleClick value = 两次点击的最大用时,默认300ms 双击注解,加入此注解,可使你的方法双击时才可进入
@IOThread ThreadType = 线程类型 切换到子线程的操作,加入此注解可使你的方法内的代码切换到子线程执行
@MainThread 无参数 切换到主线程的操作,加入此注解可使你的方法内的代码切换到主线程执行
@OnLifecycle value = Lifecycle.Event 监听生命周期的操作,加入此注解可使你的方法内的代码在对应生命周期内才去执行
@TryCatch value = 你自定义加的一个flag 加入此注解可为您的方法包裹一层 try catch 代码
@Permission tag = 自定义标记
value = 权限的字符串数组
申请权限的操作,加入此注解可使您的代码在获取权限后才执行
@Scheduled initialDelay = 延迟开始时间
interval = 间隔
repeatCount = 重复次数
isOnMainThread = 是否主线程
id = 唯一标识
定时任务,加入此注解,可使你的方法每隔一段时间执行一次,调用AndroidAop.shutdownNow(id)或AndroidAop.shutdown(id)可停止
@Delay delay = 延迟时间
isOnMainThread = 是否主线程
id = 唯一标识
延迟任务,加入此注解,可使你的方法延迟一段时间执行,调用AndroidAop.shutdownNow(id)或AndroidAop.shutdown(id)可取消
@CheckNetwork tag = 自定义标记
toastText = 无网络时toast提示
invokeListener = 是否接管检查网络逻辑
检查网络是否可用,加入此注解可使你的方法在有网络才可进去
@CustomIntercept value = 你自定义加的一个字符串数组的flag 自定义拦截,配合 AndroidAop.setOnCustomInterceptListener 使用,属于万金油

上述注解使用示例都在这,还有这,还有这

  • @OnLifecycle

    • 1、@OnLifecycle 加到的方法所属对象必须是属于直接或间接继承自 FragmentActivity 或 Fragment的方法才有用,或者注解方法的对象实现 LifecycleOwner 也可以
    • 2、如果第1点不符合的情况下,可以给切面方法第一个参数设置为第1点的类型,在调用切面方法传入也是可以的,例如:
public class StaticClass {
    @SingleClick(5000)
    @OnLifecycle(Lifecycle.Event.ON_RESUME)
    public static void onStaticPermission(MainActivity activity, int maxSelect , ThirdActivity.OnPhotoSelectListener back){
        back.onBack();
    }

}
  • @TryCatch 使用此注解你可以设置以下设置(非必须)
AndroidAop.INSTANCE.setOnThrowableListener(new OnThrowableListener() {
    @Nullable
    @Override
    public Object handleThrowable(@NonNull String flag, @Nullable Throwable throwable,TryCatch tryCatch) {
        // TODO: 2023/11/11 发生异常可根据你当时传入的flag作出相应处理,如果需要改写返回值,则在 return 处返回即可
        return 3;
    }
});
  • @Permission 使用此注解必须配合以下设置(⚠️此步为必须设置的,否则是没效果的)

💡💡💡完善使用启示

AndroidAop.INSTANCE.setOnPermissionsInterceptListener(new OnPermissionsInterceptListener() {
    @SuppressLint("CheckResult")
    @Override
    public void requestPermission(@NonNull ProceedJoinPoint joinPoint, @NonNull Permission permission, @NonNull OnRequestPermissionListener call) {
        Object target = joinPoint.getTarget();
        String[] permissions = permission.value();
        if (target instanceof FragmentActivity){
            RxPermissions rxPermissions = new RxPermissions((FragmentActivity) target);
            rxPermissions.requestEach(permissions)
                .subscribe(permissionResult -> {
                    call.onCall(permissionResult.granted);
                    if (!permissionResult.granted && target instanceof PermissionRejectListener) {
                        ((PermissionRejectListener) target).onReject(permission,permissionResult);
                    }
                });
        }else if (target instanceof Fragment){
            RxPermissions rxPermissions = new RxPermissions((Fragment) target);
            rxPermissions.requestEach(permissions)
                .subscribe(permissionResult -> {
                    call.onCall(permissionResult.granted);
                    if (!permissionResult.granted && target instanceof PermissionRejectListener) {
                        ((PermissionRejectListener) target).onReject(permission,permissionResult);
                    }
                });
        }else {
            // TODO: target 不是 FragmentActivity 或 Fragment ,说明注解所在方法不在其中,请自行处理这种情况
            // 建议:切点方法第一个参数可以设置为 FragmentActivity 或 Fragment ,然后 joinPoint.args[0] 就可以拿到
        }
    }
});
  • @CustomIntercept 使用此注解你必须配合以下设置(⚠️此步为必须设置的,否则还有什么意义呢?)
AndroidAop.INSTANCE.setOnCustomInterceptListener(new OnCustomInterceptListener() {
    @Nullable
    @Override
    public Object invoke(@NonNull ProceedJoinPoint joinPoint, @NonNull CustomIntercept customIntercept) {
        // TODO: 2023/11/11 在此写你的逻辑 在合适的地方调用 joinPoint.proceed(),
        //  joinPoint.proceed(args)可以修改方法传入的参数,如果需要改写返回值,则在 return 处返回即可

        return null;
    }
});
  • @CheckNetwork 使用此注解你可以配合以下设置 权限是必须加的
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

以下设置为可选设置项

AndroidAop.INSTANCE.setOnCheckNetworkListener(new OnCheckNetworkListener() {
    @Nullable
    @Override
    public Object invoke(@NonNull ProceedJoinPoint joinPoint, @NonNull CheckNetwork checkNetwork, boolean availableNetwork) {
        return null;
    }
});

在使用时 invokeListener 设置为true,即可进入上边回调

@CheckNetwork(invokeListener = true)
fun toSecondActivity(){
    startActivity(Intent(this,SecondActivity::class.java))
}

另外内置 Toast 可以让你接管(意思不是说你自己写的 Toast 会走这个回调,而是这个库使用 Toast 时会回调这里)

AndroidAop.INSTANCE.setOnToastListener(new OnToastListener() {
    @Override
    public void onToast(@NonNull Context context, @NonNull CharSequence text, int duration) {
        
    }
});

👆上边的监听,最好放到你的 application 中

此外本库也同样支持让你自己做切面,实现起来非常简单!

本库通过以下五种注解,实现自定义切面

  • @AndroidAopPointCut 是为方法加注解的切面
  • @AndroidAopMatchClassMethod 是匹配类的方法的切面
  • @AndroidAopReplaceClass 是替换方法调用的
  • @AndroidAopModifyExtendsClass 是修改继承类
  • @AndroidAopCollectMethod 是收集继承类

一、@AndroidAopPointCut 是在方法上通过注解的形式做切面的,上述中注解都是通过这个做的,详细使用请看wiki文档

下面以 @CustomIntercept 为例介绍下该如何使用

  • 创建注解(将 @AndroidAopPointCut 加到你的注解上)
@AndroidAopPointCut(CustomInterceptCut::class)
@Target(
        AnnotationTarget.FUNCTION,
        AnnotationTarget.PROPERTY_GETTER,
        AnnotationTarget.PROPERTY_SETTER
)
@Retention(
        AnnotationRetention.RUNTIME
)
annotation class CustomIntercept(vararg val value: String = [])
Java写法:
@AndroidAopPointCut(CustomInterceptCut.class)
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomIntercept {
    String[] value() default {};
}
  • 创建注解处理切面的类(需要实现 BasePointCut 接口,它的泛型填上边的注解)
class CustomInterceptCut : BasePointCut<CustomIntercept> {
    override fun invoke(
        joinPoint: ProceedJoinPoint,
        annotation: CustomIntercept //annotation就是你加到方法上的注解
    ): Any? {
        // 在此写你的逻辑
        // joinPoint.proceed() 表示继续执行切点方法的逻辑,不调用此方法不会执行切点方法里边的代码
        // 关于 ProceedJoinPoint 可以看wiki 文档,详细点击下方链接
        return joinPoint.proceed()
    }
}

关于 ProceedJoinPoint 使用说明,下文的 ProceedJoinPoint 同理

  • 使用

直接将你写的注解加到任意一个方法上,例如加到了 onCustomIntercept() 当 onCustomIntercept() 被调用时首先会进入到上文提到的 CustomInterceptCut 的 invoke 方法上

@CustomIntercept("我是自定义数据")
fun onCustomIntercept(){
    
}

二、@AndroidAopMatchClassMethod 是做匹配某类及其对应方法的切面的

匹配方法支持精准匹配,点此看wiki详细使用文档

  • 例子一
package com.flyjingfish.test_lib;

public class TestMatch {
    public void test1(int value1,String value2){

    }

    public String test2(int value1,String value2){
        return value1+value2;
    }
}

假如 TestMatch 是要匹配的类,而你想要匹配到 test2 这个方法,下边是匹配写法:

package com.flyjingfish.test_lib.mycut;

@AndroidAopMatchClassMethod(
        targetClassName = "com.flyjingfish.test_lib.TestMatch",
        methodName = ["test2"],
        type = MatchType.SELF
)
class MatchTestMatchMethod : MatchClassMethod {
  override fun invoke(joinPoint: ProceedJoinPoint, methodName: String): Any? {
    Log.e("MatchTestMatchMethod","======"+methodName+",getParameterTypes="+joinPoint.getTargetMethod().getParameterTypes().length);
    // 在此写你的逻辑 
    //不想执行原来方法逻辑,👇就不调用下边这句
    return joinPoint.proceed()
  }
}

可以看到上方 AndroidAopMatchClassMethod 设置的 type 是 MatchType.SELF 表示只匹配 TestMatch 这个类自身,不考虑其子类

⚠️⚠️⚠️ 不是所有类都可以Hook进去,type 类型为 SELF 时,targetClassName 所设置的类必须是安装包里的代码。例如:Toast 这个类在 android.jar 里边是不行的

  • 例子二

假如想 Hook 所有的 android.view.View.OnClickListener 的 onClick,说白了就是想全局监测所有的设置 OnClickListener 的点击事件,代码如下:

@AndroidAopMatchClassMethod(
    targetClassName = "android.view.View.OnClickListener",
    methodName = ["onClick"],
    type = MatchType.EXTENDS //type 一定是 EXTENDS 因为你想 hook 所有继承了 OnClickListener 的类
)
class MatchOnClick : MatchClassMethod {
//    @SingleClick(5000) //联合 @SingleClick ,给所有点击增加防多点,6不6
    override fun invoke(joinPoint: ProceedJoinPoint, methodName: String): Any? {
        Log.e("MatchOnClick", "=====invoke=====$methodName")
        return joinPoint.proceed()
    }
}

可以看到上方 AndroidAopMatchClassMethod 设置的 type 是 MatchType.EXTENDS 表示匹配所有继承自 OnClickListener 的子类,另外更多继承方式,请参考Wiki文档

⚠️注意:如果子类没有该方法,则切面无效,另外对同一个类的同一个方法不要做多次匹配,否则只有一个会生效

匹配切面实用场景:

  • 例如你想做退出登陆逻辑时可以使用上边这个,只要在页面内跳转就可以检测是否需要退出登陆

  • 又或者你想在三方库某个方法上设置切面,可以直接设置对应类名,对应方法,然后 type = MatchType.SELF,这样可以侵入三方库的代码,当然这么做记得修改上文提到的 androidAopConfig 的配置

三、@AndroidAopReplaceClass 是做替换方法调用的

@AndroidAopReplaceClass 和 @AndroidAopReplaceMethod 配合使用

  • 注意这种方式和前两种的有着本质的区别,前两种关注的是方法的执行,并且会自动保留可以执行原有逻辑的方法(即ProceedJoinPoint);
  • 这个关注的是方法的调用,是将所有调用的地方替换为您设置的类的静态方法,并且不会自动保留执行原有逻辑的方法
  • 这个方式的优点在于“相当于”可以监测到某些系统方法(android.jar里的代码)的调用,前两者不具备这个特点,所以如果不是基于此种需求,建议使用 @AndroidAopMatchClassMethod

替换方法调用详细使用方法,点此看wiki详细使用文档

  • Java写法
@AndroidAopReplaceClass(
        "android.widget.Toast"
)
public class ReplaceToast {
    @AndroidAopReplaceMethod(
            "android.widget.Toast makeText(android.content.Context, java.lang.CharSequence, int)"
    )
    //  因为被替换方法是静态的,所以参数类型及顺序和被替换方法一一对应
    public static Toast makeText(Context context, CharSequence text, int duration) {
        return Toast.makeText(context, "ReplaceToast-"+text, duration);
    }
    @AndroidAopReplaceMethod(
            "void setGravity(int , int , int )"
    )
    //  因为被替换方法不是静态方法,所以参数第一个是被替换类,之后的参数和被替换方法一一对应
    public static void setGravity(Toast toast,int gravity, int xOffset, int yOffset) {
        toast.setGravity(Gravity.CENTER, xOffset, yOffset);
    }
    @AndroidAopReplaceMethod(
            "void show()"
    )
    //  虽然被替换方法没有参数,但因为它不是静态方法,所以第一个参数仍然是被替换类
    public static void show(Toast toast) {
        toast.show();
    }
}

该例意思就是凡是代码中写Toast.makeTextToast.show ...的地方都被替换成ReplaceToast.makeTextReplaceToast.show ...

  • Kotlin写法
@AndroidAopReplaceClass("android.util.Log")
object ReplaceLog {
    @AndroidAopReplaceMethod("int e(java.lang.String,java.lang.String)")
    @JvmStatic
    fun e( tag:String, msg:String) :Int{
        return Log.e(tag, "ReplaceLog-$msg")
    }
}

该例意思就是凡是代码中写Log.e的地方都被替换成ReplaceLog.e

如果函数是 suspend 修饰的,点此看详细说明

四、@AndroidAopModifyExtendsClass 是修改目标类的继承类详细使用方式

通常是在某个类的继承关系中替换掉其中一层,然后重写一些函数,在重写的函数中加入一些你想加的逻辑代码,起到监听、改写原有逻辑的作用

如下例所示,就是要把 AppCompatImageView 的继承类替换成 ReplaceImageView

应用场景:非侵入式地实现监控大图加载的功能

@AndroidAopModifyExtendsClass("androidx.appcompat.widget.AppCompatImageView")
public class ReplaceImageView extends ImageView {
    public ReplaceImageView(@NonNull Context context) {
        super(context);
    }
    public ReplaceImageView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ReplaceImageView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setImageDrawable(@Nullable Drawable drawable) {
        super.setImageDrawable(drawable);
        //做一些监测或者再次修改
    }
}

五、@AndroidAopCollectMethod 是收集继承类详细使用方式

使用起来极其简单,示例代码已经说明了

  • Kotlin
object InitCollect {
    private val collects = mutableListOf<SubApplication>()
    private val collectClazz: MutableList<Class<out SubApplication>> = mutableListOf()

    @AndroidAopCollectMethod
    @JvmStatic
    fun collect(sub: SubApplication){
      collects.add(sub)
    }
    @AndroidAopCollectMethod
    @JvmStatic
    fun collect2(sub:Class<out SubApplication>){
      collectClazz.add(sub)
    }
  //直接调这个方法(方法名不限)上边的函数会被悉数回调
    fun init(application: Application){
        for (collect in collects) {
            collect.onCreate(application)
        }
    }
}
  • Java
public class InitCollect2 {
    private static final List<SubApplication2> collects = new ArrayList<>();
    private static final List<Class<? extends SubApplication2>> collectClazz = new ArrayList<>();
    @AndroidAopCollectMethod
    public static void collect(SubApplication2 sub){
        collects.add(sub);
    }

    @AndroidAopCollectMethod
    public static void collect3(Class<? extends SubApplication2> sub){
        collectClazz.add(sub);
    }
  //直接调这个方法(方法名不限)上边的函数会被悉数回调
    public static void init(Application application){
        Log.e("InitCollect2","----init----");
        for (SubApplication2 collect : collects) {
            collect.onCreate(application);
        }
    }
}

常见问题

1、Build时报错 "ZipFile invalid LOC header (bad signature)"

  • 请重启Android Studio,然后 clean 项目

2、 同一个方法存在多个注解或匹配切面时,怎么处理的

  • 多个切面叠加到一个方法上时注解优先于匹配切面(上文的匹配切面),注解切面之间从上到下依次执行
  • 调用 proceed 才会执行下一个切面,多个切面中最后一个切面执行 proceed 才会调用切入方法内的代码
  • 在前边切面中调用 proceed(args) 可更新方法传入参数,并在下一个切面中也会拿到上一层更新的参数
  • 存在异步调用proceed时,第一个异步调用 proceed 切面的返回值(就是 invoke 的返回值)就是切入方法的返回值;否则没有异步调用proceed,则返回值就是最后一个切面的返回值

3、 想 Hook 安装包以外的代码?

  • AndroidAOP 这个库顾名思义就不是 Hook 库,它是致力于打造 AOP **的库,所以它只能 Hook 安装包以内的代码

此资源库自带混淆规则,并且会自动导入,正常情况下无需手动导入。

赞赏

都看到这里了,如果您喜欢 AndroidAOP,或感觉 AndroidAOP 帮助到了您,可以点右上角“Star”支持一下,您的支持就是我的动力,谢谢~ 😃

如果感觉 AndroidAOP 为您节约了大量开发时间、为您的项目增光添彩,您也可以扫描下面的二维码,请作者喝杯咖啡 ☕

如果在捐赠留言中备注名称,将会被记录到列表中~ 如果你也是github开源作者,捐赠时可以留下github项目地址或者个人主页地址,链接将会被添加到列表中

联系方式

最后推荐我写的另外一些库

androidaop's People

Contributors

flyjingfish avatar jailedbird avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

androidaop's Issues

如何拦截三方库的方法使用自己的实现

三方库:

public class LocaleTransform {
    public static Locale getLanguage(int language) {
    }
}

如果我要修改三方库的 " java.util.Locale getLanguage(int) " 方法, 需要怎么操作? 修改后自己的逻辑代码写在哪儿?
我没看懂文档的描述.

classes.jar文件删除问题

目前集成的版本是1.4.7,在使用aop库之后,每次编译都会出现classes.jar文件删不掉的错误提示,需要手动去任务管理器的资源监视器删除,但是每次编译都会出现这样的问题,请问这个与集成aop是否有关系,aop是否会导致在编译时classes.jar可能删不掉的问题?
image

image

编译报错

AGP 8.0+
gradle 8.2
api 'io.github.FlyJingFish.AndroidAop:android-aop-core:1.4.2'
api 'io.github.FlyJingFish.AndroidAop:android-aop-annotation:1.4.2'
ksp 'io.github.FlyJingFish.AndroidAop:android-aop-ksp:1.4.2'
开发工具(最新稳定版)
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:8.2.2'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21'
classpath 'com.tencent.vasdolly:plugin:3.0.6'
classpath 'com.huawei.agconnect:agcp:1.9.1.300'
}
}
plugins {
id "io.github.FlyJingFish.AndroidAop.android-aop" version "1.4.8" apply false
id 'com.google.devtools.ksp' version '1.8.0-1.0.9' apply false
id 'cn.therouter.agp8' version '1.2.2' apply false
id "io.github.qq549631030.android-junk-code" version "1.3.3" apply false
}

QQ截图20240328173350

引入plugins插件之后,android{} 方法块报错 AssertionError: Number of arguments should not be less than number of parameters, but: parameters=5, args=4

描述一下大概怎么回事

例如使用什么功能时会这样
引入插件之后,android{} 方法块报错
Internal error occurred while analyzing this expression: AssertionError: Number of arguments should not be less than number of parameters, but: parameters=5, args=4

并不影响编译流程,可以正常注入切面使用,就是出现这个报错一片红很难受,而且android{}代码块里的代码提示和补全会失效,十分影响开发效率。不确定具体是怎么回事,我创了个新的空白项目测试只引入AndroidAOP一样会出现一样的报错,可以排除是依赖导致的问题,我推测可能是AGP的问题,但也不确定,实在束手无策了,想问问有没有什么办法能解决。

你的代码

把你的出现错误的代码关键部分贴出来
image
image

错误日志

把错误日志贴出来
Internal error occurred while analyzing this expression: AssertionError: Number of arguments should not be less than number of parameters, but: parameters=5, args=4

库的版本号:

说明库版本号

  • flyjingfish_aop_version: 1.5.9
  • Android Stuidio Version: Android Studio Iguana | 2023.2.1
  • agp_version: 8.2.0
  • kotlin_version: 1.9.20
  • gradle_wrapper_version: gradle-8.2
  • jdk_version: 17

如果可以的话,告诉我作者你的版本配置,我看能不能调成一样的,看看是不是哪个东西的版本问题。

支持系统方法Hook吗

比如想hook 主工程、子工程、三方库中 所有的buttonClick事件 或者 textView的setText方法,用这个能做吗? (并不需要真正hook系统方法,应该是通过调用的地方hook入口实现,类似aspectj)

Toast Aop不成功

代码为
@AndroidAopMatchClassMethod( targetClassName = "android.widget.Toast", methodName = ["show"], type = MatchType.EXTENDS ) class ToastAop : MatchClassMethod { override fun invoke(joinPoint: ProceedJoinPoint, methodName: String): Any? { Log.e( "MatchTestMatchMethod", "======" + methodName + ",getParameterTypes=" + joinPoint.getTargetMethod() .getParameterTypes().size ); return joinPoint.proceed() } }
把这里换成
@AndroidAopMatchClassMethod( targetClassName = "android.view.View.OnClickListener", methodName = ["onClick"], type = MatchType.EXTENDS )
就可以了 所以我想是不是不支持Toast。
然后我看有个AndroidAop.setOnToastListener,试了一下,onToast方法也没有执行。

Hook内部类时没有生效

描述一下大概怎么回事

在Hook内部类时没有生效

你的代码

@AndroidAopReplaceClass("android.provider.Settings$Secure")
public class SettingsSecureHook {
//    invoke-static {v0, v1}, Landroid/provider/Settings$Secure;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;
    @AndroidAopReplaceMethod("java.lang.String getString(android.content.ContentResolver, java.lang.String)")
    public static String getString(ContentResolver resolver, String name) {
        Log.d("tag", "getString: " + name);
        return "";
    }

    @AndroidAopReplaceMethod("java.lang.String getString(android.content.ContentResolver, java.lang.String, int)")
    public static String getStringForUser(ContentResolver resolver, String name, int userHandle) {
        Log.d("tag", "getStringForUser: " + name);
        return "";
    }
}
// 生成的class
@AopClass
public final class `SettingsSystemHook$$AndroidAopClass` {
  @AopReplaceMethod(
    targetClassName = "android.provider.Settings${'$'}System",
    invokeClassName = "im.weshine.compliance.SettingsSystemHook",
  )
  public final fun aopConfigMethod() {
  }
}
调用的代码
String androidId = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID);
Log.d("tag", "androidid = "+androidId);

错误日志

过滤tag后只有调用的日志,没有被hook的日志。我在hook WifiInfo的getIpAddress和getMacAddress是成功的,只有hook内部类时没有成功。

@AndroidAopReplaceClass("android.net.wifi.WifiInfo")
object WifiInfoDelegate {
    @AndroidAopReplaceMethod("int getIpAddress()")
    @JvmStatic
    fun getIpAddress(info: WifiInfo) = 0

    @AndroidAopReplaceMethod("java.lang.String getMacAddress()")
    @JvmStatic
    fun getMacAddress(info: WifiInfo) = "02:00:00:00:00:00"
}

库的版本号:

1.4.7

示例运行出错

描述一下大概怎么回事

运行示例

你的代码

运行SecondActivity Scheduled时出错

错误日志

FATAL EXCEPTION: main
Process: com.flyjingfish.androidaop, PID: 11763
java.lang.RuntimeException: java.lang.NoSuchMethodException: lambda$onCreate$1 [class android.view.View]
at com.flyjingfish.android_aop_annotation.AndroidAopJoinPoint.setArgs(AndroidAopJoinPoint.java:179)
at com.flyjingfish.androidaop.SecondActivity.lambda$onCreate$1$com-flyjingfish-androidaop-SecondActivity(Unknown Source:31)
at com.flyjingfish.androidaop.SecondActivity$$ExternalSyntheticLambda1.onClick(Unknown Source:2)
at android.view.View.performClick(View.java:6294)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1194)
at android.view.View$PerformClick.run(View.java:24774)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6518)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.NoSuchMethodException: lambda$onCreate$1 [class android.view.View]
at java.lang.Class.getMethod(Class.java:2068)
at java.lang.Class.getDeclaredMethod(Class.java:2047)
at com.flyjingfish.android_aop_annotation.AndroidAopJoinPoint.setArgs(AndroidAopJoinPoint.java:173)
at com.flyjingfish.androidaop.SecondActivity.lambda$onCreate$1$com-flyjingfish-androidaop-SecondActivity(Unknown Source:31) 
at com.flyjingfish.androidaop.SecondActivity$$ExternalSyntheticLambda1.onClick(Unknown Source:2) 
at android.view.View.performClick(View.java:6294) 
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1194) 
at android.view.View$PerformClick.run(View.java:24774) 
at android.os.Handler.handleCallback(Handler.java:790) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:164) 
at android.app.ActivityThread.main(ActivityThread.java:6518) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

库的版本号:

最新的

对于运行时动态织入代码的支持

详细说明功能

请问是否考虑不仅仅是编译时静态织入代码,新增运行时动态织入代码功能呢?
有如下场景:比如在安全隐私管控上(如读取用户手机信息、imei、权限申请等),大多都会接入第三方库或者 sdk 之类的,这些库如果是正常静态代码调用相关 api,那目前的编译时织入代码没问题,但如果是通过 c 层反射调用或者通过下发插件之类的形式,那么就无法进行相关管控和检测。
所以希望增加运行时动态织入代码的能力支持。

Merge jar error entry:[module-info.class], error message:java.util.zip.ZipException: duplicate entry: module-info.class,通常情况下你需要先重启Android Studio,然后clean一下项目即可,如果还有问题请到Github联系作者

描述一下大概怎么回事
duplicate entry: module-info.class,通常情况下你需要先重启Android Studio,然后clean一下项目即可,如果还有问题请到Github联系作者
配置完成一直是这个错误,我全部清理过,还是提示这个

你的代码
已经按照首页配置配置成功
java为17版本

错误日志
Merge jar error entry:[META-INF/versions/9/module-info.class], error message:java.lang.NullPointerException: Parameter specified as non-null is null: method com.flyjingfish.android_aop_plugin.beans.ClassSuperInfo., parameter superName
Merge jar error entry:[META-INF/versions/9/module-info.class], error message:java.lang.NullPointerException: Parameter specified as non-null is null: method com.flyjingfish.android_aop_plugin.beans.ClassSuperInfo., parameter superName
Merge jar error entry:[META-INF/versions/9/module-info.class], error message:java.lang.NullPointerException: Parameter specified as non-null is null: method com.flyjingfish.android_aop_plugin.beans.ClassSuperInfo., parameter superName
Merge jar error entry:[module-info.class], error message:java.lang.NullPointerException: Parameter specified as non-null is null: method com.flyjingfish.android_aop_plugin.beans.ClassSuperInfo., parameter superName
Merge jar error entry:[module-info.class], error message:java.lang.NullPointerException: Parameter specified as non-null is null: method com.flyjingfish.android_aop_plugin.beans.ClassSuperInfo., parameter superName
Merge jar error entry:[module-info.class], error message:java.lang.NullPointerException: Parameter specified as non-null is null: method com.flyjingfish.android_aop_plugin.beans.ClassSuperInfo., parameter superName
Merge jar error entry:[META-INF/versions/9/module-info.class], error message:java.lang.NullPointerException: Parameter specified as non-null is null: method com.flyjingfish.android_aop_plugin.beans.ClassSuperInfo., parameter superName
Merge jar error entry:[META-INF/versions/9/module-info.class], error message:java.lang.NullPointerException: Parameter specified as non-null is null: method com.flyjingfish.android_aop_plugin.beans.ClassSuperInfo., parameter superName

详细日志
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:debugAssembleAndroidAopTask'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:149)
at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:282)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:147)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:135)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:338)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:325)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:318)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:304)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:49)
Caused by: java.lang.RuntimeException: Merge jar error entry:[module-info.class], error message:java.util.zip.ZipException: duplicate entry: module-info.class,通常情况下你需要先重启Android Studio,然后clean一下项目即可,如果还有问题请到Github联系作者
at com.flyjingfish.android_aop_plugin.AssembleAndroidAopTask.wovenIntoCode(AssembleAndroidAopTask.kt:336)
at com.flyjingfish.android_aop_plugin.AssembleAndroidAopTask.scanFile(AssembleAndroidAopTask.kt:71)
at com.flyjingfish.android_aop_plugin.AssembleAndroidAopTask.taskAction(AssembleAndroidAopTask.kt:61)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:125)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:58)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
at org.gradle.api.internal.tasks.execution.TaskExecution$3.run(TaskExecution.java:242)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeAction(TaskExecution.java:227)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:210)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeWithPreviousOutputFiles(TaskExecution.java:193)
at org.gradle.api.internal.tasks.execution.TaskExecution.execute(TaskExecution.java:166)
at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:93)
at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:44)
at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:57)
at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:54)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:54)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:44)
at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:67)
at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:37)
at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:41)
at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:74)
at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:50)
at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:28)
at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.executeDelegateBroadcastingChanges(CaptureStateAfterExecutionStep.java:100)
at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:72)
at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:50)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:40)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:29)
at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:166)
at org.gradle.internal.execution.steps.BuildCacheStep.lambda$execute$1(BuildCacheStep.java:70)
at org.gradle.internal.Either$Right.fold(Either.java:175)
at org.gradle.internal.execution.caching.CachingState.fold(CachingState.java:59)
at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:68)
at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:46)
at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:36)
at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:25)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:36)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:22)
at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:91)
at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$2(SkipUpToDateStep.java:55)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:37)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:65)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:36)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:76)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:37)
at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:94)
at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:49)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:71)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:45)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.executeWithNonEmptySources(SkipEmptyWorkStep.java:177)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:81)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:53)
at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:32)
at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:21)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:36)
at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:23)
at org.gradle.internal.execution.steps.CleanupStaleOutputsStep.execute(CleanupStaleOutputsStep.java:75)
at org.gradle.internal.execution.steps.CleanupStaleOutputsStep.execute(CleanupStaleOutputsStep.java:41)
at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:32)
at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:287)
at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30)
at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:21)
at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37)
at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27)
at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:42)
at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:31)
at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:64)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:146)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:135)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:338)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:325)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:318)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:304)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:49)

库的版本号:
1.2.1

AndroidAopMatchClassMethod 匹配类中所有的方法

详细说明功能

我在使用AndroidAopMatchClassMethod时,发现其方法名methodName参数是必选项,这样就无法对匹配类的所有方法做处理,希望能解惑。比如我要统计,onCreate 方法中引用的init1、init2等方法的耗时,用起来很不方便

从1.6.2升级版本到1.6.8时出现错误

描述一下大概怎么回事

升级版本时候出现错误,回退使用1.6.2可以使用

你的代码

plugins {
id 'com.android.application' version '8.2.1' apply false
id 'com.android.library' version '8.2.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
id "io.github.FlyJingFish.AndroidAop.android-aop" version "1.6.8"
id 'com.google.devtools.ksp' version '1.8.0-1.0.9' apply false
}
app中的依赖:
//aop begin
implementation 'io.github.FlyJingFish.AndroidAop:android-aop-core:1.6.8'
implementation 'io.github.FlyJingFish.AndroidAop:android-aop-annotation:1.6.8'
ksp 'io.github.FlyJingFish.AndroidAop:android-aop-ksp:1.6.8'
//aop end

错误日志

  • Exception is:
    org.gradle.api.plugins.InvalidPluginException: An exception occurred applying plugin request [id: 'io.github.FlyJingFish.AndroidAop.android-aop', version: '1.6.8']
    at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.exceptionOccurred(DefaultPluginRequestApplicator.java:222)
    at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugin(DefaultPluginRequestApplicator.java:204)
    at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyLegacyPlugin(DefaultPluginRequestApplicator.java:157)
    at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.access$300(DefaultPluginRequestApplicator.java:60)
    at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator$1$1.lambda$addLegacy$0(DefaultPluginRequestApplicator.java:113)
    at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.lambda$applyPlugins$0(DefaultPluginRequestApplicator.java:142)
    at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugins(DefaultPluginRequestApplicator.java:142)
    at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:117)
    at org.gradle.configuration.BuildOperationScriptPlugin$1.run(BuildOperationScriptPlugin.java:65)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
    at org.gradle.configuration.BuildOperationScriptPlugin.lambda$apply$0(BuildOperationScriptPlugin.java:62)
    at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:44)
    at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:62)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$applyToMutableState$1(DefaultProjectStateRegistry.java:395)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.fromMutableState(DefaultProjectStateRegistry.java:413)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.applyToMutableState(DefaultProjectStateRegistry.java:394)
    at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:46)
    at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:27)
    at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:35)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.lambda$run$0(LifecycleProjectEvaluator.java:109)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$applyToMutableState$1(DefaultProjectStateRegistry.java:395)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$fromMutableState$2(DefaultProjectStateRegistry.java:418)
    at org.gradle.internal.work.DefaultWorkerLeaseService.withReplacedLocks(DefaultWorkerLeaseService.java:345)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.fromMutableState(DefaultProjectStateRegistry.java:418)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.applyToMutableState(DefaultProjectStateRegistry.java:394)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:100)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:72)
    at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:782)
    at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:156)
    at org.gradle.api.internal.project.ProjectLifecycleController.lambda$ensureSelfConfigured$2(ProjectLifecycleController.java:84)
    at org.gradle.internal.model.StateTransitionController.lambda$doTransition$14(StateTransitionController.java:255)
    at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
    at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:254)
    at org.gradle.internal.model.StateTransitionController.lambda$maybeTransitionIfNotCurrentlyTransitioning$10(StateTransitionController.java:199)
    at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:34)
    at org.gradle.internal.model.StateTransitionController.maybeTransitionIfNotCurrentlyTransitioning(StateTransitionController.java:195)
    at org.gradle.api.internal.project.ProjectLifecycleController.ensureSelfConfigured(ProjectLifecycleController.java:84)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.ensureConfigured(DefaultProjectStateRegistry.java:369)
    at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:33)
    at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:47)
    at org.gradle.configuration.DefaultProjectsPreparer.prepareProjects(DefaultProjectsPreparer.java:42)
    at org.gradle.configuration.BuildTreePreparingProjectsPreparer.prepareProjects(BuildTreePreparingProjectsPreparer.java:65)
    at org.gradle.configuration.BuildOperationFiringProjectsPreparer$ConfigureBuild.run(BuildOperationFiringProjectsPreparer.java:52)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
    at org.gradle.configuration.BuildOperationFiringProjectsPreparer.prepareProjects(BuildOperationFiringProjectsPreparer.java:40)
    at org.gradle.initialization.VintageBuildModelController.lambda$prepareProjects$2(VintageBuildModelController.java:84)
    at org.gradle.internal.model.StateTransitionController.lambda$doTransition$14(StateTransitionController.java:255)
    at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
    at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:254)
    at org.gradle.internal.model.StateTransitionController.lambda$transitionIfNotPreviously$11(StateTransitionController.java:213)
    at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:34)
    at org.gradle.internal.model.StateTransitionController.transitionIfNotPreviously(StateTransitionController.java:209)
    at org.gradle.initialization.VintageBuildModelController.prepareProjects(VintageBuildModelController.java:84)
    at org.gradle.initialization.VintageBuildModelController.getConfiguredModel(VintageBuildModelController.java:64)
    at org.gradle.internal.build.DefaultBuildLifecycleController.lambda$withProjectsConfigured$1(DefaultBuildLifecycleController.java:130)
    at org.gradle.internal.model.StateTransitionController.lambda$notInState$3(StateTransitionController.java:132)
    at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:44)
    at org.gradle.internal.model.StateTransitionController.notInState(StateTransitionController.java:128)
    at org.gradle.internal.build.DefaultBuildLifecycleController.withProjectsConfigured(DefaultBuildLifecycleController.java:130)
    at org.gradle.internal.build.DefaultBuildToolingModelController.locateBuilderForTarget(DefaultBuildToolingModelController.java:57)
    at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator$DefaultBuildTreeModelController.lambda$locateBuilderForTarget$0(DefaultBuildTreeModelCreator.java:73)
    at org.gradle.internal.build.DefaultBuildLifecycleController.withToolingModels(DefaultBuildLifecycleController.java:278)
    at org.gradle.internal.build.AbstractBuildState.withToolingModels(AbstractBuildState.java:140)
    at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator$DefaultBuildTreeModelController.locateBuilderForTarget(DefaultBuildTreeModelCreator.java:73)
    at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator$DefaultBuildTreeModelController.locateBuilderForDefaultTarget(DefaultBuildTreeModelCreator.java:68)
    at org.gradle.tooling.internal.provider.runner.DefaultBuildController.getTarget(DefaultBuildController.java:157)
    at org.gradle.tooling.internal.provider.runner.DefaultBuildController.getModel(DefaultBuildController.java:101)
    at org.gradle.tooling.internal.consumer.connection.ParameterAwareBuildControllerAdapter.getModel(ParameterAwareBuildControllerAdapter.java:39)
    at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.getModel(UnparameterizedBuildController.java:113)
    at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.getModel(NestedActionAwareBuildControllerAdapter.java:31)
    at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.findModel(UnparameterizedBuildController.java:97)
    at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.findModel(NestedActionAwareBuildControllerAdapter.java:31)
    at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.findModel(UnparameterizedBuildController.java:81)
    at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.findModel(NestedActionAwareBuildControllerAdapter.java:31)
    at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.findModel(UnparameterizedBuildController.java:66)
    at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.findModel(NestedActionAwareBuildControllerAdapter.java:31)
    at org.jetbrains.plugins.gradle.model.ProjectImportAction.execute(ProjectImportAction.java:126)
    at org.jetbrains.plugins.gradle.model.ProjectImportAction.execute(ProjectImportAction.java:43)
    at org.gradle.tooling.internal.consumer.connection.InternalBuildActionAdapter.execute(InternalBuildActionAdapter.java:64)
    at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner$ActionAdapter.runAction(AbstractClientProvidedBuildActionRunner.java:131)
    at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner$ActionAdapter.beforeTasks(AbstractClientProvidedBuildActionRunner.java:99)
    at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator.beforeTasks(DefaultBuildTreeModelCreator.java:52)
    at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.lambda$fromBuildModel$2(DefaultBuildTreeLifecycleController.java:74)
    at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.lambda$runBuild$4(DefaultBuildTreeLifecycleController.java:98)
    at org.gradle.internal.model.StateTransitionController.lambda$transition$6(StateTransitionController.java:169)
    at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
    at org.gradle.internal.model.StateTransitionController.lambda$transition$7(StateTransitionController.java:169)
    at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:44)
    at org.gradle.internal.model.StateTransitionController.transition(StateTransitionController.java:169)
    at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.runBuild(DefaultBuildTreeLifecycleController.java:95)
    at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.fromBuildModel(DefaultBuildTreeLifecycleController.java:73)
    at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner.runClientAction(AbstractClientProvidedBuildActionRunner.java:43)
    at org.gradle.tooling.internal.provider.runner.ClientProvidedPhasedActionRunner.run(ClientProvidedPhasedActionRunner.java:53)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.internal.buildtree.ProblemReportingBuildActionRunner.run(ProblemReportingBuildActionRunner.java:49)
    at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:65)
    at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:140)
    at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:41)
    at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.lambda$execute$0(RootBuildLifecycleBuildActionExecutor.java:40)
    at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:122)
    at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.execute(RootBuildLifecycleBuildActionExecutor.java:40)
    at org.gradle.internal.buildtree.InitDeprecationLoggingActionExecutor.execute(InitDeprecationLoggingActionExecutor.java:58)
    at org.gradle.internal.buildtree.DefaultBuildTreeContext.execute(DefaultBuildTreeContext.java:40)
    at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.lambda$execute$0(BuildTreeLifecycleBuildActionExecutor.java:65)
    at org.gradle.internal.buildtree.BuildTreeState.run(BuildTreeState.java:53)
    at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.execute(BuildTreeLifecycleBuildActionExecutor.java:65)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$3.call(RunAsBuildOperationBuildActionExecutor.java:61)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$3.call(RunAsBuildOperationBuildActionExecutor.java:57)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor.execute(RunAsBuildOperationBuildActionExecutor.java:57)
    at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.lambda$execute$0(RunAsWorkerThreadBuildActionExecutor.java:36)
    at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:249)
    at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:109)
    at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.execute(RunAsWorkerThreadBuildActionExecutor.java:36)
    at org.gradle.tooling.internal.provider.continuous.ContinuousBuildActionExecutor.execute(ContinuousBuildActionExecutor.java:110)
    at org.gradle.tooling.internal.provider.SubscribableBuildActionExecutor.execute(SubscribableBuildActionExecutor.java:64)
    at org.gradle.internal.session.DefaultBuildSessionContext.execute(DefaultBuildSessionContext.java:46)
    at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter$ActionImpl.apply(BuildSessionLifecycleBuildActionExecuter.java:100)
    at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter$ActionImpl.apply(BuildSessionLifecycleBuildActionExecuter.java:88)
    at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:69)
    at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter.execute(BuildSessionLifecycleBuildActionExecuter.java:62)
    at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter.execute(BuildSessionLifecycleBuildActionExecuter.java:41)
    at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64)
    at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
    at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:50)
    at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:38)
    at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:47)
    at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:31)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:65)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
    at org.gradle.util.internal.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:64)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
    Caused by: org.gradle.api.internal.plugins.PluginApplicationException: Failed to apply plugin 'io.github.FlyJingFish.AndroidAop.android-aop'.
    at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:173)
    at org.gradle.api.internal.plugins.DefaultPluginManager.apply(DefaultPluginManager.java:146)
    at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.lambda$applyLegacyPlugin$2(DefaultPluginRequestApplicator.java:159)
    at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugin(DefaultPluginRequestApplicator.java:199)
    ... 181 more
    Caused by: java.lang.NullPointerException: null cannot be cast to non-null type com.android.build.gradle.BaseExtension
    at com.flyjingfish.android_aop_plugin.plugin.CompilePlugin.apply(CompilePlugin.kt:30)
    at com.flyjingfish.android_aop_plugin.AndroidAopPlugin.apply(AndroidAopPlugin.kt:13)
    at com.flyjingfish.android_aop_plugin.AndroidAopPlugin.apply(AndroidAopPlugin.kt:9)
    at org.gradle.api.internal.plugins.ImperativeOnlyPluginTarget.applyImperative(ImperativeOnlyPluginTarget.java:43)
    at org.gradle.api.internal.plugins.RuleBasedPluginTarget.applyImperative(RuleBasedPluginTarget.java:51)
    at org.gradle.api.internal.plugins.DefaultPluginManager.addPlugin(DefaultPluginManager.java:187)
    at org.gradle.api.internal.plugins.DefaultPluginManager.access$100(DefaultPluginManager.java:52)
    at org.gradle.api.internal.plugins.DefaultPluginManager$AddPluginBuildOperation.run(DefaultPluginManager.java:282)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
    at org.gradle.api.internal.plugins.DefaultPluginManager.lambda$doApply$0(DefaultPluginManager.java:167)
    at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:44)
    at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:166)
    ... 184 more

CONFIGURE FAILED in 428ms

库的版本号:

1.6.8 当前最新

AndroidAopPointCut 注解无效 (include 包名问题, 使用者问题)

描述一下大概怎么回事

使用 AndroidAopPointCut 不生效, 自定义注解和注解处理类在 library 中, 在应用层的方法上标注 @clickEvent(), 最终 ClickAop 类的 invoke 方法没有回调

你的代码

以下为定义的注解

@AndroidAopPointCut(ClickAop::class)
@target(AnnotationTarget.FUNCTION)
@retention(AnnotationRetention.RUNTIME)
annotation class ClickEvent(val clickName: String, val clickInfo: String)

以下为注解处理类

class ClickAop: BasePointCut {
override fun invoke(joinPoint: ProceedJoinPoint, anno: ClickEvent): Any? {
ClickTrack.trackClickEvent(anno.clickName)
return joinPoint.proceed()
}
}

错误日志

库的版本号:

1.4.7

打denug包就行,打release包就报错 java.util.NoSuchElementException

描述一下大概怎么回事

例如使用什么功能时会这样
打denug包就行,打release包就报错

你的代码

把你的出现错误的代码关键部分贴出来
androidAop.debugMode = true
androidAop.debugMode.variantOnlyDebug = true
androidAop.reflectInvokeMethod = false
androidAop.reflectInvokeMethod.variantOnlyDebug = false

0 mavenLocal 1 SonatypeCache 2 mavenCentral

KSP Incremental processing

https://kotlinlang.org/docs/ksp-incremental.html#program-elements

ksp.incremental.log=true

track classpath

ksp.incremental.intermodule=true

错误日志

把错误日志贴出来

Process: com.example.kotlinplus, PID: 8065
java.lang.RuntimeException: Unable to create application com.example.kotlinplus.App: java.util.NoSuchElementException
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5428)
at android.app.ActivityThread.-wrap2(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1551)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6141)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
Caused by: java.util.NoSuchElementException
at java.util.ArrayList$Itr.next(ArrayList.java:834)
at com.flyjingfish.android_aop_annotation.AndroidAopJoinPoint.joinPointExecute(AndroidAopJoinPoint.java:106)
at com.flyjingfish.test_lib.collect.InitCollect2.init(InitCollect2.java)
at com.example.kotlinplus.App.onCreate(Unknown Source)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1024)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5425)
at android.app.ActivityThread.-wrap2(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1551) 
at android.os.Handler.dispatchMessage(Handler.java:103) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6141) 

                                                                                                	at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802) 

库的版本号:

说明库版本号
库版本:1.9.2

使用build.gradle.kts 引入 id 'android.aop'后报错

描述一下大概怎么回事

例如使用什么功能时会这样

你的代码

把你的出现错误的代码关键部分贴出来

错误日志

把错误日志贴出来

库的版本号:

说明库版本号
kotlin版本1.9.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.