自定义的动态加载用dexLoader
github:https://github.com/andoop/Dload
(1)自定义JAR模块化使用的一般步骤(非通用性):
(*0)整体结构
<1>项目结构
app依赖dloadlib, dloadplugin依赖dloadlib
app需要先注册lib里的宿主activity
<activity android:name="cn.andoop.android.dloadlib.DLoadActivity"
android:screenOrientation="portrait"/>
(*1)调用流程
<1>MainActivity调用
Dload.getInstance(this).showList();
<2> Dload加载过程-->cn.andoop.android.dloadlib在中间桥梁件包中
public void init(DloadListenerdloadListener){
DexExcutor.getInstance(context).init(dloadListener);
dloadProxy=new DloadProxy();
}
(1)DloadListener这里面是回调函数, 包括onSuccess onStart onProgress onFail等等,当加载模块的时候, 宿主能知道过程.
(2)DexExcutor
<1>通过DexClassLoader加载jar文件
获取dexClassLoader
dexClassLoader = newDexClassLoader(filepath+File.separator+MConstans.jarname, filepath,null,context.getClassLoader());
获取动态模块里的类, 通过类名
Class<?> dynamic_class =dexClassLoader.loadClass(className);
return dynamic_class.newInstance();
public void showList(){
dloadProxy.showList(context);
}
(1)DloadProxy
实现了Idload, (动态模块也实现了Idload, 他俩都需要重写showList)
来调用动态模块里的类显示出来
//实例化动态工程中的类,这个类实现了Idload接口
Idload newInstance = (Idload)DexExcutor.getInstance(context).newInstance("cn.andoop.android.dloadplugin.DloadImp");
//真正调用动态工程中的功能
newInstance.showList(context);
<3>DloadImp--cn.andoop.android.dloadplugin在动态模块包中
调用了DLoadActivity.start(context,"cn.andoop.android.dloadplugin.ui.ListFragment", null);
<4>DLoadActivity-->在中间件桥梁lib中, 且在app中注册了
第三步中传递过来的fragment的名字, 正好用来反射, 获取插件中的fragment,来更新自己的view
通过类名,反射获取到对应的类。既Fragment
Fragment fragment = (Fragment) DexExcutor.getInstance(this)
.newInstance(mClassName);
<5>插件fragment的实现
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
ListItem listItem = data.get(position);
Bundle bundle = new Bundle();
bundle.putSerializable("item",listItem);
DLoadActivity.start(getActivity(),"cn.andoop.android.dloadplugin.ui.DetailFragment", bundle);
}
(*2)编译过程
(1)在plugin build.gradle中自定义task
task buildLib (type: Jar,dependsOn:'build'){
from ('build/intermediates/classes/release')
//包含资源目录
from ('src/main/assets/')
//from fileTree(dir:'src/main',includes: ['assets/**'])
}
(2)执行编译任务
(3)将jar转化为dex jar
命令格式:dx --dex--output=out.jar in.jar
cdE:\android_dev\sdk\sdk\build-tools\23.0.2\ e: dx --dex--output=F:\projects\mprojects\DLoad\builddex\dex\plugin.jarF:\projects\mprojects\DLoad\builddex\dloadplugin.jar
最后,将生成的plugin.jar放入宿主工程的assets目录即可(本工程是这样做的,真正开发中,jar往往会放在服务端,宿主去检查时候需要更新插件),本工程只为演示而生,更多变化,以及完善,这都需要你结合实际开发而去应对。