本帖最后由 小白 于 2015-3-7 12:40 编辑
就像网上网上有些朋友说的 dex文件的方法数貌似有上限,在网上找了好久也没找到可以完全把整个dex文件放在外部加载的方法 下面这个方法,是我从某个游戏中提取的,贴出代码,如果有错误之处,还望指点出来
转自:http://blog.csdn.net/zhuanshenai/article/details/43890235小坑说了:过年还在敲代码,活该没对象
[Java] 纯文本查看 复制代码 package com.example.dextest;
import android.app.Application;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import dalvik.system.DexClassLoader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Myapp extends Application {
private static String AssetsDexFilePath = "_data";// Assets文件夹下的jar文件
private static String DexDir = "dex";
private static String ExtractedDexFileName = "_data.jar";// 导出
private static String TAG = "packer";
private Application mApp;
//ContextWrapper contextWrapper;
public Myapp() {
super();
}
@Override
public void onTerminate() {
// TODO Auto-generated method stub
super.onTerminate();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
if (this.mApp != null) {
this.mApp.onConfigurationChanged(newConfig);
}
}
@Override
public void onLowMemory() {
// TODO Auto-generated method stub
super.onLowMemory();
if(this.mApp != null) {
this.mApp.onLowMemory();
}
}
@Override
public void onTrimMemory(int level) {
// TODO Auto-generated method stub
super.onTrimMemory(level);
if(this.mApp != null) {
this.mApp.onTerminate();
}
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
copyDex();
String dexfilepath = getDir(DexDir, 0).getPath();
setApkClassLoader(new DexClassLoader(getDir(DexDir, 0).getPath() + "/" + ExtractedDexFileName, dexfilepath, getApplicationInfo().nativeLibraryDir, getClassLoader()));
//如果程序原来存在application 下面这个 就是替换原来application
//this.mApp = this.getClassLoader().loadClass(this.getPackageManager().getApplicationInfo( this.getPackageName(), 128).metaData.getString("packerApp")).newInstance();
Method v7;
try {
v7 = Class.forName("android.content.ContextWrapper").getDeclaredMethod("attachBaseContext",
Context.class);
v7.setAccessible(true);
v7.invoke(this);
v7.setAccessible(false);
/*如果存在原来的application
*v7.invoke(this.mApp, this);
*v7.setAccessible(false);
*this.mApp.onCreate();
*
*/
//this.mApp.onCreate();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**类加载器
* @param paramClassLoader
*/
@SuppressWarnings("unused")
private void setApkClassLoader(ClassLoader paramClassLoader) {
try {
Class localClass = Class.forName("android.app.ActivityThread");
Object localObject1 = localClass.getMethod("currentActivityThread", new Class[0]).invoke(null, new Object[0]);
Field localField1 = localClass.getDeclaredField("mPackages");
localField1.setAccessible(true);
Object localObject2 = localField1.get(localObject1);
localField1.setAccessible(false);
Method localMethod = localObject2.getClass().getMethod("get", new Class[] { Object.class });
Object[] arrayOfObject = new Object[1];
arrayOfObject[0] = getPackageName();
Object localObject3 = ((WeakReference)localMethod.invoke(localObject2, arrayOfObject)).get();
Field localField2 = localObject3.getClass().getDeclaredField("mClassLoader");
localField2.setAccessible(true);
localField2.set(localObject3, paramClassLoader);
localField2.setAccessible(false);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e(TAG, "err 2");
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e(TAG, "err 3");
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e(TAG, "err 4");
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e(TAG, "err 5");
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e(TAG, "err 6");
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e(TAG, "err 1");
}
}
/**
* 复制要加载jar文件
*/
private void copyDex() {
deleteFile(DexDir);// 如果文件存在则删除文件
File dexFile = getDir(DexDir, 0);// 需要导出的的文件路径
try {
InputStream localInputStream = getAssets().open(AssetsDexFilePath);// 获取Assets下的文件
FileOutputStream localFileOutputStream = new FileOutputStream(new File(dexFile,
ExtractedDexFileName));
byte[] arrayOfByte = new byte[1024];
//int i = localInputStream.read(arrayOfByte);
for (;;)
{
int i = localInputStream.read(arrayOfByte);
if (i == -1) {
break;
}
localFileOutputStream.write(arrayOfByte, 0, i);
localFileOutputStream.flush();
}
localFileOutputStream.close();
localInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e(TAG, "exception in copyDex: " + e.toString());
return;
}
}
}
附件地址:http://pan.baidu.com/s/1bn0Hs7P
|