本期专栏目讨论插件化开发. 插件化涉及的东西很多, 所以我们需要多个维度去学习. 大概分为 5 个部分: 预备知识, 入门, 进阶, 系列, 类库. 一步一步深入了解插件的原理. 本专栏会不定时更新相关内容, 请留意更新的消息. 请加入 QQ 群: 149581646. 会统一通知最新的文章.
基础
1.Java 类加载器
类加载器 (class loader) 是 Java™中的一个很重要的概念. 类加载器负责加载 Java 类的字节代码到 Java 虚拟机中. 本文首先详细介绍了 Java 类加载器的基本概念, 包括代理模式, 加载类的具体过程和线程上下文类加载器等, 接着介绍如何开发自己的类加载器, 最后介绍了类加载器在 web 容器和 OSGi™中的应用.
2. 反射原理
Java 提供的反射機制允許您於執行時期動態載入類別, 檢視類別資訊, 生成物件或操作生成的物件, 要舉反射機制的一個應用實例, 就是在整合式開發環境中所提供的方法提示或是類別檢視工具, 另外像 JSP 中的 JavaBean 自動收集請求資訊也使用到反射, 而一些軟體開發框架 (Framework) 也常見到反射機制的使用, 以達到動態載入使用者自訂類別的目的.
3. 代理模式及 Java 实现动态代理
定义: 给某个对象提供一个代理对象, 并由代理对象控制对于原对象的访问, 即客户不直接操控原对象, 而是通过代理对象间接地操控原对象.
入门
1.Android 动态加载 dex 技术初探
Android 使用 Dalvik 虚拟机加载可执行程序, 所以不能直接加载基于 class 的 jar, 而是需要将 class 转化为 dex 字节码, 从而执行代码. 优化后的字节码文件可以存在一个. jar 中, 只要其内部存放的是. dex 即可使用.
2.Android 插件化入门
开发者将插件代码封装成 Jar 或者 APK. 宿主下载或者从本地加载 Jar 或者 APK 到宿主中. 将宿主调用插件中的算法或者 Android 特定的 Class(如 Activity)
3. 插件化开发 - 动态加载技术加载已安装和未安装的 apk
动态加载技术就是使用类加载器加载相应的 apk,dex,jar(必须含有 dex 文件), 再通过反射获得该 apk,dex,jar 内部的资源 (class, 图片, color 等等) 进而供宿主 App 使用.
4.Android 动态加载技术三个关键问题详解 https://blog.tingyun.com/web/article/detail/166
动态加载技术 (也叫插件化技术) 在技术驱动型的公司中扮演着相当重要的角色, 当项目越来越庞大的时候, 需要通过插件化来减轻应用的内存和 CPU 占用, 还可以实现热插拔, 即在不发布新版本的情况下更新某些模块.
进阶
1. 携程 Android App 插件化和动态加载实践
携程 Android App 的插件化和动态加载框架已上线半年, 经历了初期的探索和持续的打磨优化, 新框架和工程配置经受住了生产实践的考验. 本文将详细介绍 Android 平台插件式开发和动态加载技术的原理和实现细节, 回顾携程 Android App 的架构演化过程, 期望我们的经验能帮助到更多的 Android 工程师.
2. 动态加载 APK 原理分享
被加载的 apk 称之为插件, 因为机制类似于生物学的 "寄生", 加载了插件的应用也被称为宿主. 往往不是所有的 apk 都可作为插件被加载, 往往需要遵循一定的 "开发规范", 还需要插件项目引入某种 API 类库, 业界通常都是这么做的.
3.Android 插件化的一种实现 http://www.cnblogs.com/coding-way/p/4669591.html
Android 的插件化已经是老生常谈的话题了, 插件化的好处有很多: 解除代码耦合, 插件支持热插拔, 静默升级, 从根本上解决 65K 属性和方法的 bug 等等. 下面给大家介绍一下我们正在用的差价化框架. 本片主要以类图的方式向大家介绍插件话框架的实现.
4. 蘑菇街 App 的组件化之路 http://mogu.io/117-117
随着我街业务的蓬勃发展, 产品和运营随时上新功能新活动的需求越来越强烈, 经常可以听到 "有个功能我想周 x 上, 行不行". 行么? 当然是不行啦, 上新功能得发新版本啊, 到时候费时费力打乱开发节奏不说, 覆盖率也是个问题.
5.DynamicLoadApk 源码解析
DynamicLoadApk 是一个开源的 Android 插件化框架. 插件化的优点包括:(1) 模块解耦,(2) 动态升级,(3) 高效并行开发(编译速度更快) (4) 按需加载, 内存占用更低等等 DynamicLoadApk 提供了 3 种开发方式, 让开发者在无需理解其工作原理的情况下快速的集成插件化功能.
6.Android apk 动态加载机制的研究
问题是这样的: 我们知道, apk 必须安装才能运行, 如果不安装要是也能运行该多好啊, 事实上, 这不是完全不可能的, 尽管它比较难实现. 在理论层面上, 我们可以通过一个宿主程序来运行一些未安装的 apk, 当然, 实践层面上也能实现, 不过这对未安装的 apk 有要求. 我们的想法是这样的, 首先要明白 apk 未安装是不能被直接调起来.
7. 美团 Android DEX 自动拆包及动态加载简介
作为一个 Android 开发者, 在开发应用时, 随着业务规模发展到一定程度, 不断地加入新功能, 添加新的类库, 代码在急剧的膨胀, 相应的 apk 包的大小也急剧增加, 那么终有一天, 你会不幸遇到这个错误.
8. 途牛原创 | 途牛 Android App 的插件实现
途牛的插件化是基于 dynamic-load-apk(GitHub)实现的. 定义了宿主和插件的通信方式, 使得两者能够互起对方的页面, 调用彼此的功能. 同时对 activity 的启动方式 singletask 等进行了模式实现, 并增加了对 Service 的支持等. 总之使得插件开发最大限度的保持着原有的 Android 开发习惯.
9. Android apk 资源加载和 activity 生命周期管理
博主分析了 Android 中 apk 的动态加载机制, 并在文章的最后指出需要解决的两个复杂问题: 资源的访问和 activity 生命周期的管理, 而本文将会分析这两个复杂问题的解决方法.
10.APK 动态加载框架 (DL) 解析
首先要说的是动态加载技术 (或者说插件化) 在技术驱动型的公司中扮演这相当重要的角色, 当项目越来越庞大的时候, 需要通过插件化来减轻应用的内存和 CPU 占用, 还可以实现热插拔, 即在不发布新版本的情况下更新某些模块.
系列
1.Kaedea---Android 动态加载技术 简单易懂的介绍 https://segmentfault.com/a/1190000004062866
我们很早开始就在 Android 项目中采用了动态加载技术, 主要目的是为了达到让用户不用重新安装 APK 就能升级应用的功能(特别是 SDK 项目), 这样一来不但可以大大提高应用新版本的覆盖率, 也减少了服务器对旧版本接口兼容的压力, 同时如果也可以快速修复一些线上的 BUG.
2.Kaedea---Android 动态加载基础 ClassLoader 的工作机制 https://segmentfault.com/a/1190000004062880
早期使用过 Eclipse 等 Java 编写的软件的同学可能比较熟悉, Eclipse 可以加载许多第三方的插件(或者叫扩展), 这就是动态加载. 这些插件大多是一些 Jar 包, 而使用插件其实就是动态加载 Jar 包里的 Class 进行工作.
3.Kaedea---Android 动态加载补充 加载 SD 卡的 SO 库 https://segmentfault.com/a/1190000004062899
Android 中 JNI 的使用其实就包含了动态加载, App 运行时动态加载. so 库并通过 JNI 调用其封装好的方法. 后者一般是使用 NDK 工具从 C/C++ 代码编译而成, 运行在 Native 层, 效率会比执行在虚拟机的 Java 代码高很多, 所以 Android 中经常通过动态加载. so 库来完成一些对性能比较有需求的工作(比如 T9 搜索, 或者 Bitmap 的解码, 图片高斯模糊处理等).
4.Kaedea---Android 动态加载入门 简单加载模式 https://segmentfault.com/a/1190000004062952
Java 程序中, JVM 虚拟机是通过类加载器 ClassLoader 加载. jar 文件里面的类的. Android 也类似, 不过 Android 用的是 Dalvik/ART 虚拟机, 不是 JVM, 也不能直接加载. jar 文件, 而是加载 dex 文件.
5.Kaedea---Android 动态加载进阶 代理 Activity 模式 https://segmentfault.com/a/1190000004062972
简单模式中, 使用 ClassLoader 加载外部的 Dex 或 Apk 文件, 可以加载一些本地 App 不存在的类, 从而执行一些新的代码逻辑. 但是使用这种方法却不能直接启动插件里的 Activity.
6.Kaedea---Android 动态加载黑科技 动态创建 Activity 模式 https://segmentfault.com/a/1190000004077469
还记得我们在代理 Activity 模式里谈到启动插件 APK 里的 Activity 的两个难题吗, 由于插件里的 Activity 没在主项目的 Manifest 里面注册, 所以无法经历系统 Framework 层级的一系列初始化过程, 最终导致获得的 Activity 实例并没有生命周期和无法使用 res 资源.
7. 尼古拉斯 --- 插件开发基础篇: 动态加载技术解读
在目前的软硬件环境下, Native App 与 Web App 在用户体验上有着明显的优势, 但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端, 造成较差的用户体验, 而这也恰恰是 Web App 的优势. 本文对网上 Android 动态加载 jar 的资料进行梳理和实践在这里与大家一起分享, 试图改善频繁升级这一弊病.
8. 尼古拉斯 --- 插件开发开篇: 类加载器分析
这篇文章主要介绍了 Android 中主要的两个类加载器: PathClassLoader 和 DexClassLoader, 他们的区别, 联系, 用法等问题, 以及我们在制作插件的过程中会遇到哪些常见的问题. 这篇文章也是后续两篇文章的基础, 因为如果不了解这两个类的话, 我们将无法进行后续的操作.
9. 尼古拉斯 --- 插件开发中篇: 资源加载问题(换肤原理解析)
这篇文章主要通过现在一些应用自带的换肤技术的解读来看看, 在开发插件的过程中如何解决一些资源加载上的问题, 这个问题为何要单独拿出来解释, 就是因为他涉及的知识很多, 也是后面一篇文章的基础, 我们在需要加载插件中的资源文件的时候.
10. 尼古拉斯 --- 插件开发终极篇: 动态加载 Activity(免安装运行程序)
这篇文章主要是讲解了如何加载插件中的 Activity. 从而实现免安装运行程序, 同时这篇文章也是对前三篇文章知识的综合使用. 下载很多应用都会使用到插件技术, 因为包的大小和一些功能的优先级来决定哪些模块可以制作成插件.
11.Weishu---Android 插件化原理解析 -- 概要
类的加载可以使用 Java 的 ClassLoader 机制, 但是对于 Android 来说, 并不是说类加载进来就可以用了, 很多组件都是有 "生命" 的; 因此对于这些有血有肉的类, 必须给它们注入活力, 也就是所谓的组件生命周期管理.
12.Weishu---Android 插件化原理解析 --Hook 机制之动态代理
使用代理机制进行 API Hook 进而达到方法增强是框架的常用手段, 比如 J2EE 框架 Spring 通过动态代理优雅地实现了 AOP 编程, 极大地提升了 Web 开发效率; 同样, 插件框架也广泛使用了代理机制来增强系统 API 从而达到插件化的目的.
13.Weishu---Android 插件化原理解析 --Hook 机制之 Binder Hook
Android 系统通过 Binder 机制给应用程序提供了一系列的系统服务, 诸如 ActivityManagerService,ClipboardManager, AudioManager 等; 这些广泛存在系统服务给应用程序提供了诸如任务管理, 音频, 视频等异常强大的功能.
14.Weishu---Android 插件化原理解析 --Hook 机制之 AMS&PMS
在前面的文章中我们介绍了 DroidPlugin 的 Hook 机制, 也就是代理方式和 Binder Hook; 插件框架通过 AOP 实现了插件使用和开发的透明性. 在讲述 DroidPlugin 如何实现四大组件的插件化之前, 有必要说明一下它对 AMS 以及 PMS 的 Hook 方式.
15.Weishu---Android 插件化原理解析 --Activity 生命周期管理
之前的 Android 插件化原理解析 系列文章揭开了 Hook 机制的神秘面纱, 现在我们手握倚天屠龙, 那么如何通过这种技术完成插件化方案呢? 具体来说, 插件中的 Activity,Service 等组件如何在 Android 系统上运行起来?
16.Weishu---Android 插件化原理解析 -- 插件加载机制
上文 Activity 生命周期管理 中我们地完成了『启动没有在 AndroidManifest.xml 中显式声明的 Activity』的任务; 通过 Hook AMS 和拦截 ActivityThread 中 H 类对于组件调度我们成功地绕过了 AndroidMAnifest.xml 的限制.
17.Weishu---Android 插件化原理解析 -- 广播的管理
在 Activity 生命周期管理 以及 插件加载机制 中我们详细讲述了插件化过程中对于 Activity 组件的处理方式, 为了实现 Activity 的插件化我们付出了相当多的努力; 那么 Android 系统的其他组件, 比如 BroadcastReceiver,Service 还有 ContentProvider, 它们又该如何处理呢?
18.Weishu---Android 插件化原理解析 --Service 的插件化
在 Activity 生命周期管理 以及 广播的管理 中我们详细探讨了 Android 系统中的 Activity,BroadcastReceiver 组件的工作原理以及它们的插件化方案, 相信读者已经对 Android Framework 和插件化技术有了一定的了解;
类库
1.DroidPlugin https://github.com/Qihoo360/DroidPlugin
是 360 手机助手在 Android 系统上实现了一种新的插件机制
2.Android-Plugin-Framework
此项目是 Android 插件开发框架完整源码及示例. 用来通过动态加载的方式在宿主程序中运行插件 APK.
3.Small https://github.com/wequick/Small
世界那么大, 组件那么小. Small, 做最轻巧的跨平台插件化框架. 里面有很详细的文档
4.dynamic-load-apk https://github.com/singwhatiwanna/dynamic-load-apk
Android 使用动态加载框架 DL 进行插件化开发
5.AndroidDynamicLoader https://github.com/mmin18/AndroidDynamicLoader
Android 动态加载框架, 他不是用代理 Activity 的方式实现而是用 Fragment 以及 Schema 的方式实现
6.DynamicAPK https://github.com/CtripMobile/DynamicAPK
实现 Android App 多 apk 插件化和动态加载, 支持资源分包和热修复. 携程 App 的插件化和动态加载框架.
7.ACDD
非代理 Android 动态部署框架
8.Android-pluginmgr https://github.com/houkx/android-pluginmgr
不需要插件规范的 apk 动态加载框架.
参考视频
1.DroidPlugin 的实现原理及其应用
Droid Plugin 是 360 手机助手在 2015 年初研发的一个全新的基于 Android 平台的插件机制.
2.Android 插件化及动态部署 http://v.youku.com/v_show/id_XNTMzMjYzMzM2.html
阿里技术沙龙第十六期《Android 插件化及动态部署》视频
微信公众号: Android 博客周刊
image
来源: http://www.jianshu.com/p/cb31ad451ced