黑马程序员技术交流社区
标题:
安卓hotPatch工具类
[打印本页]
作者:
谭世霖
时间:
2016-12-6 15:15
标题:
安卓hotPatch工具类
package com.github.lzyzsd.androidhotfixexamples;
import android.content.Context;import android.util.Log;
import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.lang.reflect.Array;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;
import dalvik.system.DexClassLoader;import dalvik.system.PathClassLoader;
/** * Created by bruce on 11/14/15. */public class DexLoaderUtil { private static final String TAG = "DexLoaderUtil"; public static final String SECONDARY_DEX_NAME = "lib.apk"; public static final String THIRD_DEX_NAME = "lib2.apk"; private static final int BUF_SIZE = 8 * 1024;
public static String getDexPath(Context context, String dexName) { return new File(context.getDir("dex", Context.MODE_PRIVATE), dexName).getAbsolutePath(); }
public static String getOptimizedDexPath(Context context) { return context.getDir("outdex", Context.MODE_PRIVATE).getAbsolutePath(); }
public static void copyDex(Context context, String dexName) { File dexInternalStoragePath = new File(context.getDir("dex", Context.MODE_PRIVATE), dexName); BufferedInputStream bis = null; OutputStream dexWriter = null;
try { bis = new BufferedInputStream(context.getAssets().open(dexName)); dexWriter = new BufferedOutputStream( new FileOutputStream(dexInternalStoragePath)); byte[] buf = new byte[BUF_SIZE]; int len; while((len = bis.read(buf, 0, BUF_SIZE)) > 0) { dexWriter.write(buf, 0, len); } dexWriter.close(); bis.close();
} catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
public static void loadAndCall(Context context, String dexName) { final File dexInternalStoragePath = new File(context.getDir("dex", Context.MODE_PRIVATE), dexName); final File optimizedDexOutputPath = context.getDir("outdex", Context.MODE_PRIVATE);
DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(), optimizedDexOutputPath.getAbsolutePath(), null, context.getClassLoader()); call(cl); }
public static void call(ClassLoader cl) { Class myClasz = null; try { myClasz = cl.loadClass("com.example.MyClass"); Object instance = myClasz.getConstructor().newInstance(); myClasz.getDeclaredMethod("test1").invoke(instance); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } }
public static synchronized Boolean injectAboveEqualApiLevel14( String dexPath, String defaultDexOptPath, String nativeLibPath, String dummyClassName) { Log.i(TAG, "--> injectAboveEqualApiLevel14"); PathClassLoader pathClassLoader = (PathClassLoader) DexLoaderUtil.class.getClassLoader(); DexClassLoader dexClassLoader = new DexClassLoader(dexPath, defaultDexOptPath, nativeLibPath, pathClassLoader); try { dexClassLoader.loadClass(dummyClassName); Object dexElements = combineArray( getDexElements(getPathList(pathClassLoader)), getDexElements(getPathList(dexClassLoader)));
Object pathList = getPathList(pathClassLoader); setField(pathList, pathList.getClass(), "dexElements", dexElements); } catch (Throwable e) { e.printStackTrace(); return false; } Log.i(TAG, "<-- injectAboveEqualApiLevel14 End."); return true; }
private static Object getPathList(Object baseDexClassLoader) throws IllegalArgumentException, NoSuchFieldException, IllegalAccessException, ClassNotFoundException { return getField(baseDexClassLoader, Class.forName("dalvik.system.BaseDexClassLoader"), "pathList"); }
private static Object getDexElements(Object paramObject) throws IllegalArgumentException, NoSuchFieldException, IllegalAccessException { return getField(paramObject, paramObject.getClass(), "dexElements"); }
private static Object getField(Object obj, Class<?> cl, String field) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Field localField = cl.getDeclaredField(field); localField.setAccessible(true); return localField.get(obj); }
private static void setField(Object obj, Class<?> cl, String field, Object value) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Field localField = cl.getDeclaredField(field); localField.setAccessible(true); localField.set(obj, value); }
private static Object combineArray(Object arrayLhs, Object arrayRhs) { Class<?> localClass = arrayLhs.getClass().getComponentType(); int i = Array.getLength(arrayLhs); int j = i + Array.getLength(arrayRhs); Object result = Array.newInstance(localClass, j); for (int k = 0; k < j; ++k) { if (k < i) { Array.set(result, k, Array.get(arrayLhs, k)); } else { Array.set(result, k, Array.get(arrayRhs, k - i)); } } return result; }}
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2