AutoRegister icon indicating copy to clipboard operation
AutoRegister copied to clipboard

实现类收集成功,注入失败

Open TokenYc opened this issue 5 years ago • 3 comments

在使用时发现了一个问题: 在管理类中,使用静态代码注入的方式时,如果持有实现类的引用不进行初始化,虽然可以收集到实现类,但是注入会失败。如:

可以注入成功的写法

public class TestManager {
    

    private static List<IInit> testList = new ArrayList<>();

    private static void inject(IInit baseTest) {
        if (baseTest != null) {
            testList.add(baseTest);
        }
    }
}
//构建成功后查看源码,可以看到插入的静态代码块

注入失败的写法:

public class TestManager {

    private static List<IInit> testList;

    private static void inject(IInit baseTest) {
        if (baseTest != null) {
            if (testList == null) {
                testList = new ArrayList<>();
            }
            testList.add(baseTest);
        }
    }
}
//构建成功后查看源码,没有插入的静态代码块

TokenYc avatar May 22 '19 09:05 TokenYc

//构建成功后查看源码 . 在哪里查看源码呢?具体路径?我在build source apt下没找到

hxiaxuetian avatar Aug 29 '19 10:08 hxiaxuetian

在android studio的build里可以看到构建时的输出。如/Users/yc/Documents/AndroidStudioProjects/AutoRegisterDemo/app/build/intermediates/transforms/auto-register/debug/33.jar 找到这个文件后用jd-gui打开,就可以看到源码了。

@hxiaxuetian

TokenYc avatar Aug 30 '19 07:08 TokenYc

@TokenYc 问题的原因是:没有静态初始化变量时,TestManager没有生成<clinit>方法(也就是static块),AutoRegister在使用ASM插入字节码时是遍历目标类中的所有方法,根据配置的方法名查找目标方法,由于<clinit>方法未生成,故没有生成代码到static块中。

临时解决方案(思路:确保类中能有<clinit>方法),以下方法人选一种即可:

  1. 在类中添加一个空的static块(如:static { })【推荐使用
  2. 在静态变量声明的同时初始化它
  3. 在类中添加其它在声明的同事初始化的变量(如: static int a = 0;

彻底修复这个问题需要将这段逻辑完善一下(这段代码):如果没有找到目标方法,则自动生成这个方法并向其中插入需要生成的注册代码。 后续我找时间实现一下。如果你有兴趣也欢迎你按照这个思路实现出来给我提个PR!

luckybilly avatar Sep 12 '19 07:09 luckybilly