这里用个例子来演示,具体流程是用Android Studio建一个Android项目并编写相应代码,然后用Eclipse编写一个java代码并打成jar包,再转换成Android能识别的dexjar包,最后先安装好APP,然后把jar包放到APP目录下,app通过反射调用jar包中的方法。
步骤
1.定义接口文件
在Eclipse中创建一个接口文件,这个接口文件也要复制一份到安卓项目中,并且包名要相同。
package com.fu.test;
/**
*
* Create by Fu
* 2017年10月16日 下午6:19:24
*
* 通用接口文件,Android项目中也需要这个文件
* 并且包名要一致
*/
public interface ILoader {
public String hellow();
//计算a+b
public int calculate(int a, int b);
}
复制一份到Android项目中同样的目录下
2.实现接口文件并生成jar包
在Eclipse中新建一个java类并实现接口,Android项目中不需要。然后通过Eclipse打成jar包,再通过Android SDK的dx工具把Eclipse生成的jar包转成Android能识别的jar包。
package com.fu.test;
/**
*
* Create by Fu
* 2017年10月16日 下午6:30:59
* 接口的实现类
*/
public class JarLoader implements ILoader {
@Override
public String hellow() {
// TODO Auto-generated method stub
return "我是后来保存的jar包";
}
@Override
public int calculate(int a, int b) {
// TODO Auto-generated method stub
return a + b;
}
}
在Eclipse中,右键工程—>Export—>Java—>JAR file
然后把生成出来的jar包复制到SDK目录下\build-tools\26.0.0中,在这里我们把jar包转成Android能识别的jar包。
在这个目录下打开cmd,或者打开cmd进入到这个目录。
执行
dx --dex --output=myloader_dex.jar myloader.jar
生成出来的myloader_dex.jar就是我们最终要放到存储目录中的jar包。
3.通过反射加载jar文件
//拿到jar文件
File path = new File(getFilesDir() + File.separator + "myloader_dex.jar");
DexClassLoader cl = new DexClassLoader(path.getAbsolutePath(), getFilesDir().getAbsolutePath(),
getFilesDir().getAbsolutePath(), getClassLoader());
Class myClass = null;
try {
// 载入JarLoader类, 并且通过反射构建JarLoader对象, 然后调用sayHi方法
myClass = cl.loadClass("com.fu.test.JarLoader"); //这里要用类的完整名称
ILoader loader = (ILoader) myClass.newInstance();
//因为我们这里也有接口文件,所有就能直接点出方法来
String hellow = loader.hellow();
int result = loader.calculate(3, 5);
Toast.makeText(MainActivity.this, hellow + ",计算结果=" + result, Toast.LENGTH_SHORT).show();
} catch (Exception exception) {
exception.printStackTrace();
}
4.运行APP并把jar包放入到存储空间进行测试
直接用Android Device Monitor放入jar包
放到/data/data/应用包名/files中,因为好像从安卓那个版本开始,通过反射加载dex文件不能从外部存储目录了,也就是SD卡,所以我就放到这里了,这个文件夹调用一下getFilesDir()就会自己生成。
效果图
这样我们就能实现不用重新安装APP,仅改变jar包中的方法,然后重新生成jar包,放到存储空间中,就会调用新的逻辑,当然如果改变接口文件的话就需要编译打包Android项目了。