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