安卓开发

android插件开发,android 插件化开发

DexClassLoader pluginClassLoader = new DexClassLoader(dexPath, optimizedDirectory, libraryPath, parentClassLoader);可动态加载的内容包括 apk、dex、jar 等

我也利用这个原理及开源项目实现了一个版本,并且整理了 Android 插件化的作用、概念以及不错的资料(包括开源项目)和解决方案。

其中包括 65535 问题,Android 插件化、Android 组件化、Android 动态加载、Android 动态升级;介绍 DexClassLoader 和 PathClassLoader 的区别;如何解决生命周期管理、资源访问问题,如何消除公共依赖

详细可见我的博客:利用 DexClassLoader 实现 Android 插件化,从而达到动态加载

编辑于 2014-09-24​赞同 211​​6 条评论​分享​收藏​喜欢收起​继续浏览内容知乎发现更大的世界打开浏览器继续知乎用户92 人赞同了该回答插件化技术发展到现在其实已经很成熟了,但是相应的问题,如果没有真正地去实践过,根本不了解其中有多少问题,会牵涉到多少技术细节,多少被外人膜拜的外表光鲜的技术大牛都被『插件化』这三个字折磨地死去活来,这对于 Android 整个生态的损害也让人无法忽视。

昨天的 MDCC ,冯森林老师提出了一个很有意思的思路『组件化』。

我们首先要想一下,我们做插件化的目的是什么?为了满足产品随时上线的需求?

为了修复因为我们对自己要求不严格而写出来的 bug ?为了向人炫耀自己的技术实力?很抱歉,如果是为了这些目的,那就真的太对不起自己是『开发者』这个如此高逼格的身份了。

做插件化真正的目的:是为了去适应并行开发,是为了解耦各个模块,是为了避免模块之间的交叉依赖,是为了加快编译速度,从而提高并行开发效率。

明确了这些,我们再来看插件化的结果,每个模块都支持独立运行测试,分为稳定的 release 版本和不稳定的 snapshot 版本,每个模块都高度解耦,没有交叉依赖,不会出现一个模块依赖了另一个模块,其中一个人改了这个模块的代码,对另一个模块造成影响。这时候,我们再看冯老师的『组件化』思想。

那么这个『组件化』是什么意思呢?我说下我自己的理解,可能不对,还请指教:

通过 gradle 配置的方式,将打 debug 包和 release 包分开。这样会有一个好处,开发一个模块,在 debug 的时候,可以打成一个 apk ,独立运行测试,可以完全独立于整个宿主 APP 的其他所有组件;待到要打 release 包的时候,再把这个模块作为一个 library ,打成 aar ,作为整个宿主 APP 的一部分。而 debug 和 release 的切换都是通过 gradle 配置,可以做到无缝切换。至于模块之间的跳转,可以用别名的方式,而不是用 Activity 和 Fragment 类名。这样所有的模块和宿主 APP 都是完全解耦的,彻底解决了并行开发的可能造成的交叉依赖等问题。

按照这个思路,我们再来看看一些其他的细节:

在 Android 里有一个比较爽的一点是,作为 library 的时候,aar 里的引用依赖,在宿主 Application 里也有同样的引用依赖,并不会打包两份到宿主 Application 里;

即然电脑可以以这种形式进行组装,哪我们android程序是不是也可以这样?答案是肯定的,我们的各个独立的功能模块都可以打包成apk,让宿主程序把apk加载进来,再运行里面的各个activity,service等

插件化的分类插件化在技术难度上可以为分两种:独立插件化和非独立插件

非独立插件是宿主程序与插件发开约定好插件开发规则,插件开发者要遵循这个规划进行开发,这种方式要求的技术难度相对来说低很多,但是增加了开发者的调用成本。类似比较成熟的解新局面方案有Small,需要说明的是small支持Android和iOS两个平台

独立插件完全支持android的兼容四大组件的大部份的属性,这种方式对于开发者可以说是完全透明,是十分完善的插件化解决方案。但是偏写这类框架需要对android底层的代码非常熟悉,要对种种api进行hook处理,所以技术要求也非常的高。类似比较成熟的方案有DroidPlugin等等非独立插件原理因为我们下载的apk里面activity没有在宿入的manifest.xml注册,如果我们直接调用startActivity方法,就会报activity没有注册的异常。我们可以在宿主activity中先注册一个代理Activity,然后通过宿主activity去调用插件里面的activity的方法。

哪我们怎样去加载我们插件apk里面的类呢?下面让我们了解下java里面几个类加载器:

DexClassLoader :可以加载文件系统上的jar、dex、apk

PathClassLoader :可以加载/data/app目录下的apk,这也意味着,它只能加载已经安装的apk

URLClassLoader :可以加载java中的jar,但是由于dalvik不能直接识别jar,所以此方法在android中无法使用,尽管还有这个类由上面的解释可以了解到我们可以通过DexClassLoader把插件apk里面的类加载出来让我们使用。

非独立插件实现首先我们先摸拟apk下载的流程,把assets目录下面的apk下载下来,存放在缓存目录中,但是下载下来我们还不能直接使用,我们还要对apk包进行以下处理

解密我们下载下来的apk包

校验apk的签名是否正确

校验apk包所需的权限是否在主包中都包函

File mApkPath = this.getDir(ProxyActivity.APK_PATH, MODE_PRIVATE);try {String mApkName = “myapplication-release-unsigned.apk”;InputStream inputStream = getResources().getAssets().open(mApkName);byte[] datas = FileUtil.readFromInputStream(inputStream);String fullPath = mApkPath.getAbsolutePath() + File.separator + mApkName;FileUtil.writeByteToFile(datas, new File(fullPath));} catch (IOException e) {e

Similar Posts

发表评论

邮箱地址不会被公开。 必填项已用*标注