A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 谭世霖 中级黑马   /  2016-12-6 15:15  /  638 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

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;    }}
来自宇宙超级黑马专属苹果客户端来自宇宙超级黑马专属苹果客户端

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马