package com.x.hookzz;

import android.app.Activity;
import android.content.pm.ApplicationInfo;
import android.widget.Toast;

import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

import dalvik.system.DexClassLoader;

/**
 * Created by kaibing.xie on 2018/3/28.
 */

public class LoadDex {

    private static DexClassLoader loader = null;

    public void cloadDex(Activity activity, ClassLoader classLoader) {

        if(loader == null) {
            ApplicationInfo activityInfo = activity.getApplicationInfo();
            String optimizedDirectory = activity.getDir("Dex", 0).getAbsolutePath();
            Logger.d("optimizedDirectory is :%s", optimizedDirectory);
            Object currentActivityThread = Refectls.invokeStaticMethod(
                    "android.app.ActivityThread", "currentActivityThread",
                    new Class[] {}, new Object[] {});
            String packageName = activity.getPackageName();
            Map<?, ?> mPackages = null;
            mPackages = (Map<?, ?>) Refectls.getFieldOjbect(
                    "android.app.ActivityThread", currentActivityThread,
                    "mPackages");
            WeakReference<?> wr = (WeakReference<?>) mPackages.get(packageName);
            loader = new DexClassLoader("/data/local/tmp/target.dex", optimizedDirectory, null, classLoader);
            Refectls.setFieldOjbect("android.app.LoadedApk", "mClassLoader",
                    wr.get(), loader);
        }
        try {
            Class cls = loader.loadClass("com.x.dex.DexFucntion");
            Object instance = cls.newInstance();
            Method m = cls.getDeclaredMethod("foo1");
            m.invoke(instance);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}