摘自 Android中的动态加载机制
>
我主要是想在应用发布出去之后,根据我后台的配置让客户端动态的加载不同的逻辑代码,以实现灵活的运营需求
项目需要,主要使用了上述作者的思路之一
开门见山了--
1.实现待会要用的动态代码部分,项目目录如下
IDynamic.java
package com.dynamic.interfaces;
public interface IDynamic {
//随便写几个方法作为测试用
void init();
void printHelloWorld();
String getString();
int getInt();
}
Dynamic.java
package com.dynamic.impl;
import com.dynamic.interfaces.IDynamic;
public class Dynamic implements IDynamic {
@Override
public void init() {
// TODO Auto-generated method stub
System.out.println("Dynamic.class --- init");
}
@Override
public void printHelloWorld() {
// TODO Auto-generated method stub
System.out.println("Dynamic.class --- printHelloWorld");
}
@Override
public String getString() {
// TODO Auto-generated method stub
System.out.println("Dynamic.class --- getString");
return "test";
}
@Override
public int getInt() {
// TODO Auto-generated method stub
System.out.println("Dynamic.class --- getInt");
return 888;
}
}
将IDynamic.java和Dynamic.javaf嗯别打成jar包,如图 :
这样就会有了dynamic.jar和dynamic_interface.jar两个jar包,dynamic_interface.jar是待会在android项目里调用的接口类,可以这么理解,在android里其实调用的是接口方法(其实现我们会将其作为jar包、dex包或者apk包,我这里用的是jar包,详细的可以看博主原文),我们在程序运行时根据自己的业务需求动态的去下载不同jar包去执行,这样就实现了我上述需求
2.加工下jar包
命令
~/software/android-sdk-macosx/build-tools/22.0.1$ ./dx --dex --output=dynamic_tmp.jar dynamic.jar
这里解释下,之所以在这个目录执行,是因为要用dx命令,我在自己sdk的这个目录找到了,所以把dynamic.jar拷贝到这个目录里执行,这个根据自己实际dx命令所在目录即可,这命令的目的是将class转成dex也就是dalvik能执行的东东,android里用的只能是dex格式
这里只是简单的走一遍流程,再者就是提示下小坑,方便大家快速上手,so 我把dynamic_tmp.jar文件push到了/mnt/sdcard/里以待android动态加载
3.使用
添加接口jar包,记得add到Library哦
private IDynamic iDynamic;//还记得这个吗,之前写的那个接口类,也就是上面那个jar包里的类
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (iDynamic != null) {
iDynamic.printHelloWorld();//好熟悉吧
}
}
});
try {
//动态包文件地址
String dexPath = "/mnt/sdcard/dynamic_tmp.jar";//手动放的文件,实际上可以动态下载
//这里注意下不要写错!!!
//动态包解压地址
File dexOutputDir = this.getDir("dex", 0);
//加载动态
DexClassLoader dexClassLoader = new DexClassLoader(dexPath, dexOutputDir.getAbsolutePath(), null, getClassLoader());
Class libProviderClazz = dexClassLoader.loadClass("com.dynamic.impl.Dynamic");
iDynamic = (IDynamic) libProviderClazz.newInstance();//创建对象了
if (iDynamic != null) {
iDynamic.init();//调个方法意思意思
}
} catch (Exception e) {
e.printStackTrace();
}
}