创建hackdex模块并创建AntilazyLoad类
看图就好了:
将AntilazyLoad单独打成hack_dex.jar包
通过以下命令来实现:
jar cvf hack.jar com.devilwwj.hackdex/*
这个命令会将AntilazyLoad类打包成hack.jar文件
dx --dex --output hack_dex.jar hack.jar
这个命令使用dx工具对hack.jar进行转化,生成hack_dex.jar文件
dx工具在我们的sdk/build-tools下
最终我们把hack_dex.jar文件放到项目的assets目录下:
使用javassist实现动态代码注入
创建buildSrc模块,这个项目是使用Groovy开发的,需要配置Groovy SDK才可以编译成功。
在这里下载Groovy SDK:http://groovy-lang.org/download.html,下载之后,配置项目user Library即可。
它里面提供了一个方法,用来向指定类的构造函数注入代码:
/**
-
植入代码
-
@param buildDir 是项目的build class目录,就是我们需要注入的class所在地
-
@param lib 这个是hackdex的目录,就是AntilazyLoad类的class文件所在地
*/
public static void process(String buildDir, String lib) {
println(lib);
ClassPool classes = ClassPool.getDefault()
classes.appendClassPath(buildDir)
classes.appendClassPath(lib)
// 将需要关联的类的构造方法中插入引用代码
CtClass c = classes.getCtClass(“com.devilwwj.hotfixdemo.BugClass”)
if (c.isFrozen()) {
c.defrost()
}
println(“添加构造方法”)
def constructor = c.getConstructors()[0];
constructor.insertBefore(“System.out.println(com.devilwwj.hackdex.AntilazyLoad.class);”)
c.writeFile(buildDir)
CtClass c1 = classes.getCtClass(“com.devilwwj.hotfixdemo.LoadBugClass”)
if (c1.isFrozen()) {
c1.defrost()
}
println(“添加构造方法”)
def constructor1 = c1.getConstructors()[0];
constructor1.insertBefore(“System.out.println(com.devilwwj.hackdex.AntilazyLoad.class);”)
c1.writeFile(buildDir)
}
配置app项目的build.gradle
上一小节创建的module提供相应的方法来让我们对项目的类进行代码注入,我们需要在build.gradle来配置让它自动来做这件事:
apply plugin: ‘com.android.application’
task(‘processWithJavassist’) << {
String classPath = file(‘build/intermediates/classes/debug’)// 项目编译class所在目录
com.devilwwj.patch.PatchClass.process(classPath, project(‘:hackdex’).buildDir.absolutePath + “/intermediates/classes/debug”) // 第二个参数是hackdex的class所在目录
}
android {
compileSdkVersion 23
buildToolsVersion “23.0.1”
defaultConfig {
applicationId “com.devilwwj.hotfixdemo”
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName “1.0”
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile(‘proguard-android.txt’),