博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用DexClassLoader动态加载dex文件
阅读量:5034 次
发布时间:2019-06-12

本文共 2228 字,大约阅读时间需要 7 分钟。

Java中也有类加载器ClassLoader,其作用是动态装载Class文件,当我们从网络下载Class文件,或者在编译时不参与而在运行时动态调用时就需要用类加载器。由于Android对class文件进行了重新打包和优化,最终APK文件中包含的是dex文件,加载这种文件就需要用到DexClassLoader。

DexClassLoader(dexPath, optimizedDirectory, libraryPath, parent)

dexPath:目标类所在的APK或者jar包,/.../xxx.jar

optimizedDirectory:从APK或者jar解压出来的dex文件存放路径

libraryPath:native库路径,可以为null

parent:父类装载器,一般为当前类的装载器、

插件类Plugin用于在运行时由宿主程序调用

public class Plugin {	public int add(int a, int b) {		return a+b;	}}
使用jar命令将其打包成jar文件

jar -cvf plugin.jar com/dl/plugin/Plugin.class
使用dx命令将其转化为android中的类格式dex文件
dx --dex --output=f:\dynamic.jar f:\Plugin.jar
将其放到手机目录中,比如放到根目录
adb push F:\dynamic.jar /

在宿主程序中动态加载调用插件类Plugin的add函数

DexClassLoader loader = new DexClassLoader("/dynamic.jar", getApplicationInfo().dataDir, null, this.getClass().getClassLoader());clazz = loader.loadClass("com.dl.plugin.Plugin");Method add = clazz.getMethod("add", Integer.TYPE,Integer.TYPE);int result = (Integer) add.invoke(clazz.newInstance(), 1,1);

首先动态加载Plugin类,然后通过反射调用add方法,完整代码如下
private Button btn;	private Class
clazz; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { if (clazz == null) { DexClassLoader loader = new DexClassLoader("/dynamic.jar", getApplicationInfo().dataDir, null, this.getClass().getClassLoader()); clazz = loader.loadClass("com.dl.plugin.Plugin"); } Method add = clazz.getMethod("add", Integer.TYPE,Integer.TYPE); int result = (Integer) add.invoke(clazz.newInstance(), 1,1); Toast.makeText(MainActivity.this, result+"", 0).show(); } catch (Exception e) { e.printStackTrace(); } } }); }

上面使用反射进行函数调用有些复杂,可以使用接口进行更方便的调用还能保持动态加载的灵活性。项目结构如下,保证接口IPlugin类名一致,包括包名。也可以通过引入jar包的形式来做。

于是就可以通过如下方式调用插件类中的代码了。

DexClassLoader loader = new DexClassLoader("/dynamic.jar", getApplicationInfo().dataDir, null, this.getClass().getClassLoader());clazz = loader.loadClass("com.dl.plugin.Plugin");IPlugin obj = (IPlugin) clazz.newInstance();int result = obj.add(1, 1);

效果:

转载于:https://www.cnblogs.com/qhyuan1992/p/5385267.html

你可能感兴趣的文章
Spring之面向切面编程AOP
查看>>
MATLAB GUI程序设计中使文本框接收多行输入的方法
查看>>
全文检索-Elasticsearch (四) elasticsearch.net 客户端
查看>>
Oracle DBMS_SESSION
查看>>
sublime复制当前行到下一行
查看>>
WPF 3D变换应用
查看>>
luogu4012 深海机器人问题 网络流
查看>>
android 拍照上传照片
查看>>
ArchLinux安装开源VMware Tools
查看>>
系统用户分析模型
查看>>
DB2 锁升级示例1
查看>>
16.RDD实战
查看>>
MainFrame知识小结(20120210)—dfsort/syncsort中的数据类型
查看>>
jsp题库 (一)小测(25/21)
查看>>
D - Flip tile
查看>>
Java连接RabbitMQ之创建连接
查看>>
开户vim编程之--cscope支持
查看>>
python数据类型图解
查看>>
C#微信登录-手机网站APP应用
查看>>
HTML5实践 -- iPhone Safari Viewport Scaling Bug
查看>>