package com.aitsuki.hotpatchdemo;
import android.app.Application;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import dalvik.system.DexClassLoader;
/**
* Created by hp on 2016/4/6.
*/
public class HotPatchApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
injectHack();
// 获取补丁,如果存在就执行注入操作
String dexPath = Environment.getExternalStorageDirectory().getAbsolutePath().concat("/patch_dex.jar");
File file = new File(dexPath);
if (file.exists()) {
inject(dexPath);
} else {
Log.e("HotPatchApplication", dexPath + "不存在");
}
}
private void injectHack() {
try {
File hackDir = getDir("hackDir", MODE_PRIVATE);
File hackJar = new File(hackDir,"hack.jar");
InputStream in = getAssets().open("hack.jar");
OutputStream out = new FileOutputStream(hackJar);
byte[] buf = new byte[1024];
int len;
while ((len= in.read(buf)) != -1) {
out.write(buf,0,len);
}
in.close();
out.close();
inject(hackJar.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 要注入的dex的路径
*
* @param path
*/
private void inject(String path) {
try {
// 获取classes的dexElements
Class<?> cl = Class.forName("dalvik.system.BaseDexClassLoader");
Object pathList = getField(cl, "pathList", getClassLoader());
Object baseElements = getField(pathList.getClass(), "dexElements", pathList);
// 获取patch_dex的dexElements(需要先加载dex)
String dexopt = getDir("dexopt", 0).getAbsolutePath();
DexClassLoader dexClassLoader = new DexClassLoader(path, dexopt, dexopt, getClassLoader());
Object obj = getField(cl, "pathList", dexClassLoader);
Object dexElements = getField(obj.getClass(), "dexElements", obj);
// 合并两个Elements
Object combineElements = combineArray(dexElements, baseElements);
// 将合并后的Element数组重新赋值给app的classLoader
setField(pathList.getClass(), "dexElements", pathList, combineElements);
//======== 以下是测试是否成功注入 =================
Object object = getField(pathList.getClass(), "dexElements", pathList);
int length = Array.getLength(object);
Log.e("BugFixApplication", "length = " + length);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
/**
* 通过反射获取对象的属性值
*/
private Object getField(Class<?> cl, String fieldName, Object object) throws NoSuchFieldException, IllegalAccessException {
Field field = cl.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(object);
}
/**
* 通过反射设置对象的属性值
*/
private void setField(Class<?> cl, String fieldName, Object object, Object value) throws NoSuchFieldException, IllegalAccessException {
Field field = cl.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
}
/**
* 通过反射合并两个数组
*/
private Object combineArray(Object firstArr, Object secondArr) {
int firstLength = Array.getLength(firstArr);
int secondLength = Array.getLength(secondArr);
int length = firstLength + secondLength;
Class<?> componentType = firstArr.getClass().getComponentType();
Object newArr = Array.newInstance(componentType, length);
for (int i = 0; i < length; i++) {
if (i < firstLength) {
Array.set(newArr, i, Array.get(firstArr, i));
} else {
Array.set(newArr, i, Array.get(secondArr, i - firstLength));
}
}
return newArr;
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
HotPatchDemo.rar (44个子文件)
HotPatchDemo
gradlew.bat 2KB
gradlew 5KB
gradle.properties 872B
app
proguard-rules.pro 654B
src
test
java
com
aitsuki
hotpatchdemo
ExampleUnitTest.java 331B
androidTest
java
com
aitsuki
hotpatchdemo
ApplicationTest.java 367B
main
res
mipmap-xxxhdpi
ic_launcher.png 10KB
drawable
mipmap-hdpi
ic_launcher.png 3KB
values
colors.xml 214B
strings.xml 78B
styles.xml 394B
dimens.xml 216B
mipmap-xxhdpi
ic_launcher.png 8KB
mipmap-mdpi
ic_launcher.png 2KB
mipmap-xhdpi
ic_launcher.png 5KB
layout
activity_main.xml 727B
values-w820dp
dimens.xml 364B
assets
hack.jar 1KB
java
com
aitsuki
hotpatchdemo
HotPatchApplication.java 5KB
Cat.java 167B
MainActivity.java 572B
AndroidManifest.xml 812B
.gitignore 8B
build.gradle 2KB
libs
gradle
wrapper
gradle-wrapper.jar 52KB
gradle-wrapper.properties 231B
patch_dex.jar 1KB
.gitignore 105B
local.properties 450B
buildsrc
src
main
groovy
com
aitsuki
plugin
PreDexTransform.groovy 3KB
Register.groovy 516B
Inject.groovy 684B
local.properties 450B
build.gradle 205B
settings.gradle 36B
hack
proguard-rules.pro 654B
src
test
java
com
aitsuki
hack
ExampleUnitTest.java 323B
androidTest
java
com
aitsuki
hack
ApplicationTest.java 359B
main
res
drawable
values
strings.xml 70B
java
com
aitsuki
hack
AntilazyLoad.java 102B
AndroidManifest.xml 275B
.gitignore 8B
build.gradle 597B
libs
build.gradle 521B
共 44 条
- 1
资源评论
- yxd三哥2017-09-17不错,感谢共享资源;
- 林佳10232017-04-25可以用,谢谢了
- m_lei2017-02-07没看懂啥意思~你这里面用到热修复了吗
- Gao-Lei2018-02-03非常好,学习到了,感谢分享
AItsuki
- 粉丝: 250
- 资源: 10
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功