android动态加载Jar/dex--原创

MeOrdinary 2013-10-10

背景:开发课题需要对应不同手机,为防止每次更换手机对系统重新开发时间上的浪费。决定把通用的一些功能拿出来,扫描,蓝牙,照相,摄像之类的这些技能,同意开发一个jar动态调用。参考了诸多前辈的网站之后,自己动手写了一下。

相关扫盲:

1. 浅谈Android虚拟机的动态加载技术 

2. android动态加载Jar/dex-农民伯伯

3.http://blog.csdn.net/qq591840685/article/details/7866115

首先对以上前辈感谢,特别是农民伯伯。

切入正题:

一、动态jar/dex的准备,根据自己业务需求封装。

1.如果是android.library=true这种项目可以直接在bin下面找到jar包(我是这种方式)。否则可以直接expot to jar 导出来。注意一些不必要的android配置文件不要打成Jar。再或者把需要打包的package新建一个java project然后编译expot to jar。

2. 第一步导出来的jar是没有被dx优化的,也就是说里面是.class文件而不是.dex文件。需要进行优化。

  很多人找不到dx在什么位置,我也是找了半天才找到。在sdk下面的platform-tools文件夹里面或者tools里面你们找找。我的就没有是从别的sdk里面找到的,不知道为什么。大家要是要的话可以留言跟我要。

用法很简单:dos 进入 tools下面 运行:

dx --dex --output=B.jar A.jar    //A.jar 是你第一步倒出来的   B.jar是优化完之后的。

  注:优化的目的是android解析.dex文件会比.class更快。上面的命令就是把A.jar里面的.class文件优化成.dex文件然后又打包成B.jar。此处就不多解释了。

3.B.jar准备好了之后,放到手机内部一个路径。注意权限问题。

4.然后就是敲写代码这里了,主要利用的是反射技术。通过上面的文章或许你们都已经了解了我就不多赘述。直接上代码:

String path = "data/ytpacer/dex/B.jar";//路径自己改
				final File file = new File(path);
				DexClassLoader cl = new DexClassLoader(file.getAbsolutePath(),
						"data/ytpacer/dex", null, getClassLoader());
				Class libProviderClazz = null;

				try {
					libProviderClazz = cl
							.loadClass("com.xxx.xxx.类名");
					Method[] methods = libProviderClazz.getDeclaredMethods();
					for (int i = 0; i < methods.length; i++) { //遍历类里所有方法
						Log.v("====", methods[i].toString());
					}
					Method start = libProviderClazz.getDeclaredMethod("start",
							Context.class);//调用start方法,参数类型是Context
					start.setAccessible(true);//未加这句之前报了一个错误:access to method denied 加上之后可以了。
					start.invoke(libProviderClazz.newInstance(),
							MainActivity.this);//调用方法传参
				
				} catch (Exception e) {
					e.printStackTrace();
				}

                           

OK 跑一下你的项目就能看到Log打出来的所有方法。

后一步可以继续封装。全部反射调用这样太累了。明天继续,今天早点回家,天不太好!

望大家多多指教,若有更好的实现方法,不采用动态加载jar的话请告知!谢谢。

相关推荐