Android插件化开篇

1,360 阅读4分钟

前言

我在很久之前就想写一系列关于插件化的博客,可是总被这样或那样的事情打断。上周终于下定决心去做这个事情。今天这篇文章是一个开篇,作用有两个:一是把吹的牛发布到网上,前面已经说过了;二是对插件化的知识做一个简单的介绍,顺便帮自己整理一下接下来的写作思路。

什么是插件化

通常,我们的app只有一个apk文件。而插件化是一种将app拆分为多个apk的技术,每一个apk都是app功能的一部分。一般,我们把app启动时由系统加载的apk称之为宿主。而宿主是可以加载其他的apk的,这些被宿主加载的apk我们称为插件。

插件化的用途

在学习一项新技能之前,我们首先要弄清楚它能为我们带来什么。那插件化能给我们带来什么呢?

  • 从项目管理角度来说:

    1. 插件化将应用的不同功能划分到一个个的插件中,便于程序的维护。
    2. 每个插件可以单独运行调试极大的提高了开发效率。
    3. 每个插件互不影响,多人协同开发更加高效。
  • 从程序运行角度来说:

    1. 按需加载插件,占用内存更少。
    2. 按需更新,更省流量。
  • 从公司运营角度来说:

    1. 实时更新,便于运营推广。
    2. 修复线上BUG,将风险降到最低。

插件化需要哪些内功

插件化像是一门十分高深的武功,它需要修习者有一定理论基础后才能修炼。那它需要哪些理论支撑呢?

  • ClassLoader

    ClassLoader是由JVM平台提供的类加载器。它允许程序从网络、硬盘甚至是内存加载Class,这就为Android插件化提供了最基础的技术保障。我们知道Android平台对字节码文件作了优化,摒弃了传统JVM需要的.jar文件,而是采用体积更小的.dex文件。因此,Android自定义了一系列ClassLoader以满足对dex加载。在这些ClassLoader中,有一个DexClassLoader,它允许我们的app加载外部的.jar和.apk文件。

  • 反射和Hook技术

    Hook的翻译是"钩子"。我们知道Android操作系统有一套自己的机制,例如,Activity启动流程、事件分发机制、资源管理机制等。有时候,这些机制无法满足我们的需求,通过系统的API也无能为力。这时候就需要Hook技术对原有流程进行拦截,然后将系统流程替换成我们自己的流程。而反射是Hook技术的一种必要手段。

  • APP安装过程

    我们知道apk文件中包含了app运行需要的Activity、Service等信息。这些信息是在程序安装过程中通过PackageManagerService解析AndroidManifest文件取得的。只有了解了这些原理,我们才能知道如何解析插件中的Activity、Service等信息。

  • 四大组件的启动流程

    单纯解析出插件的Activity、Service等信息是不行,我们期望的是这些Activity、Service等可以像我们普通App中的一样可以正常运行。这就需要我们去熟悉四大组件的启动流程,然后通过Hook技术加入宿主启动插件的Activity、Service等逻辑。

  • 资源管理

    插件化会给资源管理带来两个问题:

    1. 在Android打包编译时,gradle会为图片、文案等资源生成一个唯一的Id。在运行期,通过对资源Id的引用来查找相应的资源。由于宿主apk和各插件apk打包不是在一次gradle assemble命令中完成的,这就有可能造成多个apk中产生的资源id相同,我们称之为资源冲突

    2. 各apk中的资源是无法共享的,例如在宿主中无法引用插件中的资源。

    为了解决这两个问题,我们有必要掌握Android平台的资源管理机制。

后续文章会以什么样的方式呈现

后续文章我会采用原理+DEMO的表现形式。在每篇文章的前半部分主要是介绍原理知识;后半部分是代码Demo,这些Demo串联在一起就是一个简单的插件化框架。