package com.huanju.chajianhuatest;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.huanju.chajianhuatest.aidlmode.TestBean;
import com.huanju.chajianhuatest.ams.AMSHookHelper;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import dalvik.system.DexClassLoader;
import dalvik.system.DexFile;
/**
* @author 刘镓旗
* @date 17/2/21
*/
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// getSystemService(Context.ACTIVITY_SERVICE);
setContentView(R.layout.activity_main);
findViewById(R.id.bbb).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//这里说一下,我们真正要启动的Activity不是直接用类名.class,因为
//我们这个应用里根本没有这个类
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.huanju.chajiandemo",
"com.huanju.chajiandemo.TestActivity"));
startActivity(intent);
}
});
}
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
try {
new Thread(){
@Override
public void run() {
//创建一个属于我们自己插件的ClassLoader,我们分析过只能使用DexClassLoader
String cachePath = MainActivity.this.getCacheDir().getAbsolutePath();
String apkPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/chajian_demo.apk";
DexClassLoader mClassLoader = new DexClassLoader(apkPath, cachePath,cachePath, getClassLoader());
MyHookHelper.inject(mClassLoader);
try {
AMSHookHelper.hookActivityManagerNative();
AMSHookHelper.hookActivityThreadHandler();
} catch (Exception e) {
Log.e("Main","加载异常了 = " + e.getMessage());
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,"加载完成",Toast.LENGTH_SHORT).show();
}
});
}
}.start();
} catch (Exception e) {
e.printStackTrace();
}
}
//原来demo的方法
public static void patchClassLoader(ClassLoader cl, File apkFile, File optDexFile)
throws IllegalAccessException, NoSuchMethodException, IOException, InvocationTargetException, InstantiationException, NoSuchFieldException {
// 获取 BaseDexClassLoader : pathList
Field pathListField = DexClassLoader.class.getSuperclass().getDeclaredField("pathList");
pathListField.setAccessible(true);
Object pathListObj = pathListField.get(cl);
// 获取 PathList: Element[] dexElements
Field dexElementArray = pathListObj.getClass().getDeclaredField("dexElements");
dexElementArray.setAccessible(true);
Object[] dexElements = (Object[]) dexElementArray.get(pathListObj);
// Element 类型
Class<?> elementClass = dexElements.getClass().getComponentType();
// 创建一个数组, 用来替换原始的数组
Object[] newElements = (Object[]) Array.newInstance(elementClass, dexElements.length + 1);
// 构造插件Element(File file, boolean isDirectory, File zip, DexFile dexFile) 这个构造函数
Constructor<?> constructor = elementClass.getConstructor(File.class, boolean.class, File.class, DexFile.class);
Object o = constructor.newInstance(apkFile, false, apkFile, DexFile.loadDex(apkFile.getCanonicalPath(), optDexFile.getAbsolutePath(), 0));
Object[] toAddElementArray = new Object[] { o };
// 把原始的elements复制进去
System.arraycopy(dexElements, 0, newElements, 0, dexElements.length);
// 插件的那个element复制进去
System.arraycopy(toAddElementArray, 0, newElements, dexElements.length, toAddElementArray.length);
// 替换
dexElementArray.set(pathListObj, newElements);
}
}