- 资源代理类:
package com.hu.glmenu.hook;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Created by TT on 2017/5/31.
*/
public class PluginResources extends Resources {
/**
* Create a new Resources object on top of an existing set of assets in an
* AssetManager.
*
* @param assets Previously created AssetManager.
* @param metrics Current display metrics to consider when
* selecting/computing resource values.
* @param config Desired device configuration to consider when
*/
public PluginResources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
super(assets, metrics, config);
}
public static PluginResources getPluginResources(Resources resources,AssetManager assetManager){
PluginResources pluginResources =new PluginResources(assetManager,resources.getDisplayMetrics(),resources.getConfiguration());
return pluginResources;
}
//自定义加载插件的apk的AsserManger
public static AssetManager getPluginAssetManager(File apk) throws ClassNotFoundException {
//加载传进来的apk
Class<?> forName = Class.forName("android.content.res.AssetManager");
Method[] methods =forName.getDeclaredMethods();//拿到方法集合
for (Method method : methods) {
if(method.getName().equals("addAssetPath")){
//要找到apk的路径
try {
AssetManager assetManager =AssetManager.class.newInstance();
method.invoke(assetManager,apk.getAbsolutePath());
return assetManager;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
return null;
}
}
- 下载apk/目前通过assets:
//插件名字
fileName = "app-release.apk";
//缓存路径名
String filePath = this.getCacheDir() + File.separator + fileName;
//包名
String packageName ="com.ganqianwang.ganqianwang";
File apkfile = new File(filePath);
if(apkfile.exists()){
//存在了,直接访问
Log.e("TAG==","存在apk");
}else{
//下载
try {
InputStream is =this.getAssets().open(fileName);
FileOutputStream os =new FileOutputStream(filePath);
int lem =0;
byte[] buffer =new byte[1024];
while ((lem =is.read(buffer))!=-1){
//写入
os.write(buffer,0,lem);
}
os.close();
is.close();
Log.e("TAG==","加载完成");
} catch (IOException e) {
e.printStackTrace();
}
}
反射R文件
//反射R文件
DexClassLoader classLoader = new DexClassLoader(apkfile.getAbsolutePath(),
this.getDir(fileName, Context.MODE_PRIVATE).getAbsolutePath(), null, getClassLoader());
try {
AssetManager pluginAssetManager = PluginResources.getPluginAssetManager(apkfile);
PluginResources pluginResources = PluginResources.getPluginResources(getResources(), pluginAssetManager);Class<?> loadClass = classLoader.loadClass(packageName+".R$drawable"); Field[] declaredFields = loadClass.getDeclaredFields(); for (Field declaredField : declaredFields) { if (declaredField.getName().equals("kuang_agree")) { int animId = declaredField.getInt(R.drawable.class); Drawable drawable = pluginResources.getDrawable(animId); Log.e("TAG==","设置背景"); tv.setBackground(drawable); } } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); }