替换ClassLoader
package com.bluelesson.dummydex34;
import android.app.Application;
import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import dalvik.system.DexClassLoader;
public class DummyApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// 1. 拷贝dex到安装目录下
String path = copyDex("src.dex");
// 2. 使用DexClassLoader,加载dex
DexClassLoader dex = loadDex(path);
// 3. 替换ClassLoader
replaceClassLoader1(dex);
}
@Override
public void onCreate() {
super.onCreate();
}
// 拷贝指定的文件从assets目录中到/data/data/包名/files中
String copyDex(String dexName) {
// 获取assets目录管理器
AssetManager as = getAssets();
// 合成路径
// getFilesDir返回的就是/data/data/包名/files
String path = getFilesDir() + File.separator + dexName; // File.separator 分隔符
Log.i("15pb-log", path);
try {
// 创建文件流
FileOutputStream out = new FileOutputStream(path);
// 打开文件
InputStream is = as.open(dexName);
// 循环读取文件,拷贝到对应路径
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
// 关闭文件
out.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return "";
}
return path;
}
// 获得指定文件的dex加载器
public DexClassLoader loadDex(String path) {
// 创建dex文件的类加载器,返回DexClassLoader对象
DexClassLoader dex = new DexClassLoader(
path, // dex路径
getCacheDir().toString(), // 优化之后的文件的路径
null, // 原生库路径
getClassLoader()); // 父类加载器
return dex;
}
public void replaceClassLoader1(DexClassLoader dexClassLoader){
try {
// 1. 获取ActivityThead类对象
// android.app.ActivityThread
// 1.1 获取类类型
Class clzActivityThead = Class.forName("android.app.ActivityThread");
// 1.2 获取类方法
Method currentActivityThread = clzActivityThead.getMethod("currentActivityThread",new Class[]{});
// 1.3 调用方法
currentActivityThread.setAccessible(true);
Object objActivityThread = currentActivityThread.invoke(null);
// 2. 通过类对象获取成员变量mBoundApplication
//clzActivityThead.getDeclaredField()
Field field = clzActivityThead.getDeclaredField("mBoundApplication");
// AppBindData
field.setAccessible(true);
Object data = field.get(objActivityThread);
// 3. 获取mBoundApplication对象中的成员变量info
// 3.1 获取 AppBindData 类类型
Class clzAppBindData = Class.forName("android.app.ActivityThread$AppBindData");
// 3.2 获取成员变量info
Field field1 = clzAppBindData.getDeclaredField("info");
// 3.3 获取对应的值
//LoadedApk
field1.setAccessible(true);
Object info = field1.get(data);
// 4. 获取info对象中的mClassLoader
// 4.1 获取 LoadedApk 类型
Class clzLoadedApk = Class.forName("android.app.LoadedApk");
// 4.2 获取成员变量 mClassLoader
Field field2 = clzLoadedApk.getDeclaredField("mClassLoader");
field2.setAccessible(true);
d2.set(info,dexClassLoader);
} catch (Exception e) {
e.printStackTrace();
}
}
}