使用gradle插件修改类(onClick方法)

时间:2016-11-09 12:35:08

标签: android android-gradle gradle-plugin

我想使用gradle在所有活动中修改onClick方法,但是当我反映onClick方法时会收到错误消息,javassist.CannotCompileException:找不到android.view.View,这里是代码,整个项目是{{3 }}

public class MyTransform extends Transform{


Project project

public MyTransform(Project project) {
    this.project = project
}

@Override
String getName() {
    return "MyTrans"
}

@Override
Set<QualifiedContent.ContentType> getInputTypes() {
    return TransformManager.CONTENT_CLASS
}

// 指定Transform的作用范围
@Override
Set<QualifiedContent.Scope> getScopes() {
    return TransformManager.SCOPE_FULL_PROJECT
}

@Override
boolean isIncremental() {
    return false
}

@Override
void transform(Context context, Collection<TransformInput> inputs,
               Collection<TransformInput> referencedInputs,
               TransformOutputProvider outputProvider, boolean isIncremental)
        throws IOException, TransformException, InterruptedException {
    inputs.each {TransformInput input ->
        input.directoryInputs.each {DirectoryInput directoryInput->

            // modify onClick 
            Modifyer.injectDir(directoryInput.file.absolutePath,"com/cocoa/test")

            def dest = outputProvider.getContentLocation(directoryInput.name,
                    directoryInput.contentTypes, directoryInput.scopes,
                    Format.DIRECTORY)

            FileUtils.copyDirectory(directoryInput.file, dest)
        }
        input.jarInputs.each {JarInput jarInput->

            def jarName = jarInput.name
            def md5Name = DigestUtils.md5Hex(jarInput.file.getAbsolutePath())
            if(jarName.endsWith(".jar")) {
                jarName = jarName.substring(0,jarName.length()-4)
            }

            def dest = outputProvider.getContentLocation(jarName+md5Name,
                    jarInput.contentTypes, jarInput.scopes, Format.JAR)
            FileUtils.copyFile(jarInput.file, dest)
        }
    }
}

}

public class Modifyer {


private static ClassPool pool = ClassPool.getDefault()

public static void injectDir(String path, String packageName) {
    println "injectDir---------"
    pool.appendClassPath(path)
    File dir = new File(path)
    if (dir.isDirectory()) {
        dir.eachFileRecurse { File file ->
            String filePath = file.absolutePath

            if (filePath.endsWith(".class")
                    && !filePath.contains('R$')
                    && !filePath.contains('R.class')
                    && !filePath.contains("BuildConfig.class")) {

                int index = filePath.indexOf(packageName);

                boolean isMyPackage = index != -1;

                if (isMyPackage) {

                    int end = filePath.length() - 6 // .class = 6
                    String className = filePath.substring(index, end)
                            .replace('\\', '.').replace('/', '.')
                    //get the class <like MainActivity.class>
                    CtClass c = pool.getCtClass(className)

                    if (c.isFrozen()) {
                        c.defrost()
                    }

                    try {
                        println "injectDir---------" + c.getName()

                        CtMethod[] methods = c.getDeclaredMethods();
                        for (CtMethod m : methods) {
                            println "injectDir---------" + m.getName()
                            if (m.getName().equals("onClick")) {  //at this ,always get Exception  javassist.CannotCompileException: cannot find android.view.View


                                m.insertBefore("com.cocoa.mixpaneltest.Logger.log();");
                                println "injectDir---------" + m.getName()
                            }
                        }

                    } catch (Exception e) {
                        println "injectDir---------" + e.toString()
                    }
                    c.writeFile(path)
                    c.detach()
                }
            }
        }
    }
}

}

public class PluginImpl implements Plugin<Project> {
void apply(Project project) {
        def android = project.extensions.findByType(AppExtension)
        android.registerTransform(new MyTransform(project))

}

}

1 个答案:

答案 0 :(得分:0)

您需要将android.jar附加到类池,以便javassist可以编译。 这是一个已知问题,请检查https://github.com/realm/realm-java/issues/2703

project.android.bootClasspath.each {
        String path = it.absolutePath
        classPool.appendClassPath(path)
}