dynamic-load-apk-Apk动态加载框架使用初体验

y9RUe3 9年前

因为想要将本网站上的开源代码直接做成一个能显示效果的app,决定摸索下android的插件开发,发现只有两个开源的插件系统可选:

AndroidDynamicLoader

dynamic-load-apk

因为第一个只允许在fragment的基础上开发插件,第二个没有此限制并且是国人开发,文档比较齐全,所以选择了第二个。

 

下载dynamic-load-apk

dynamic-load-apk 简称DL框架,从github上下载DL,如下:

lib是Library,sample是例子程序,打开sample如下:

根据官方的解释,有三种模式,其中main目录下才是其推荐的独立插件模式,所以直接不管depend_on_interface这个文件夹了。

其中main-host是宿主,他需要引用DL的Library才能运行,main-plugin-a,以及main-plugin-b是插件。

 

运行sample中的宿主和插件

我将main直接import到eclispe中,并且将DL的Library也导入,将main-host添加Library依赖,运行main-host程序,当然了 显示的是没有插件,因为main-host程序需要在sdcard的根目录下建立DynamicLoadHost目录,然后DynamicLoadHost目录中放入插件的apk。这主要是因为main-host程序的代码是这样写的:

private void initData() {      String pluginFolder = Environment.getExternalStorageDirectory() + "/DynamicLoadHost";      File file = new File(pluginFolder);      File[] plugins = file.listFiles();      if (plugins == null || plugins.length == 0) {          mNoPluginTextView.setVisibility(View.VISIBLE);          return;      }      for (File plugin : plugins) {          PluginItem item = new PluginItem();          item.pluginPath = plugin.getAbsolutePath();          item.packageInfo = DLUtils.getPackageInfo(this, item.pluginPath);          if (item.packageInfo.activities != null && item.packageInfo.activities.length > 0) {              item.launcherActivityName = item.packageInfo.activities[0].name;          }          mPluginItems.add(item);          DLPluginManager.getInstance(this).loadApk(item.pluginPath);      }      mListView.setAdapter(mPluginAdapter);      mListView.setOnItemClickListener(this);      mPluginAdapter.notifyDataSetChanged();  }

pluginFolder指定为DynamicLoadHost。

当然你自己写的宿主程序完全可以指定为其他目录,甚至直接来源于网上(只是猜想),如果不支持直接加载远程的apk,我们可以先从网上下载下来,放到我们程序指定的一个目录。

接着我们再运行main-plugin-a,产生一个apk放到刚刚在sdcard建立的DynamicLoadHost目录。

然后再次打开宿主程序,点击这个插件,和预期是一致的,插件就像一个apk一样执行了。

 

尝试自己的apk

虽然官方文档已经说明插件apk需要满足一些要求(context不能用this,jar不能打包在apk中(主要是DL的jar以及surport的jar)等),但是我还是忍不住要尝试一下直接把我的apk放进sdcard的DynamicLoadHost目录,运行宿主程序,列表中能看到我的apk程序,点击,没反应。。。。。。。。。

虽然在意料之中,但是小心脏还是小小的失落。

先说下我运行的这个程序叫GossipView,在github上可以下载,因为GossipView非常简单且具有代表性,没有依赖其他库(GossipView是直接在demo中一起的),有activity,有一个自定义的GossipView。对于我准备开发的东西来说,如果这个东西都不能运行,那就没什么意义了。

我开始改造我的GossipView,让他可以作为插件了:增加了external-jars 将DL的jar放进去,并且将surport的jar也放进去,同时在.classpath中追加如下两句:

<classpathentry kind="lib" path="external-jars/dl-lib.jar"/>
<classpathentry kind="lib" path="external-jars/android-support-v4.jar"/>

这样,编译的时候就能够正常进行,但是打包的时候,就不会把上面两个jar包打入到插件apk中。

 

接下来不是要改this为that吗,改呗,我发现我的activity中只有一处用了this,替换成that,运行。得到了一个apk,但是很奇怪的是我的插件居然能直接运行,不是说那样做两个jar不会被打包进去吗怎么还能运行了呢。。。。

管他的哦,先将这次的apk放进去再说。

运行宿主,点开我的插件,报错了:

 

看来还真的是包多了,也就是说我的插件apk中其实把DL和surport的jar打包进去了。

 

我找啊找啊找,发现是自己粗心了,我在插件项目中添加了两次DL,一次是用jar,一次是直接添加了Library的依赖。fuck。

好吧改过来之后,完全可以了,只是原本我应用的白色背景变成了黑色背景。