进阶高工必备技能:Android插件化技术全解析!(附项目实战+视频分享)

第一代:dynamic-load-apk最早使用ProxyActivity这种静态代理技术,由ProxyActivity去控制插件中PluginActivity的生命周期。该种方式缺点明显,插件中的activity必须继承PluginActivity,开发时要小心处理context。而DroidPlugin通过Hook系统服务的方式启动插件中的Activity,使得开发插件的过程和开发普通的app没有什么区别,但是由于hook过多系统服务,异常复杂且不够稳定。

第二代:为了同时达到插件开发的低侵入性(像开发普通app一样开发插件)和框架的稳定性,在实现原理上都是趋近于选择尽量少的hook,并通过在manifest中预埋一些组件实现对四大组件的插件化。另外各个框架根据其设计思想都做了不同程度的扩展,其中Small更是做成了一个跨平台,组件化的开发框架。

第三代:VirtualApp比较厉害,能够完全模拟app的运行环境,能够实现app的免安装运行和双开技术。Atlas是阿里今年开源出来的一个结合组件化和热修复技术的一个app基础框架,其广泛的应用与阿里系的各个app,其号称是一个容器化框架。

插件化对于Android开发的意义

近些年,一线互联网大厂几乎对移动互联网形成了垄断,app的功能越来越多,比如下面的美团、支付宝(最近相继因为垄断问题被调查(手动狗头)):

每个app都集成了许多功能入口,美团上有“美食”、“电影”、“外卖”、“打车”等,其实每个入口都是一个app,只不过被集成到这些入口里了。想要一下如果没有插件化技术,美团、淘宝这些app会有多大?又或是对于用户而言,如果没有插件化,你的手机上面又要多下多少个APP?

不管是对于美团、阿里这些互联网IT公司而言,还是对于广大的Android用户而言,插件化技术的出现,都具有里程碑的意义。对于Android开发者而言,插件化技术已经是进阶Android高级工程师的必备技能之一。

如何学习插件化

入门知识

首先我们要知道插件化技术是属于比较复杂一个领域,复杂点在于它涉及知识点广泛,不仅仅是上层做应用架构能力,还要求我们对 Android 系统底层知识需要有一定的认知,这里简单罗列了其中会涉及的知识点:

首先,要介绍的是 Binder ,我们都知道 Android 多进程通信核心就是 Binder ,如果没有它真的寸步难行。 Binder 涉及两层技术,你可以认为它是一个中介者模式,在客户端和服务器端之间, Binder 就起到中介的作用。如果要实现四大组件的插件化,就需要在 Binder 上做修改, Binder 服务端的内容没办法修改,只能改客户端的代码,而且四大组件的每个组件的客户端都不一样,这个就需要深入研究了。学习Binder的最好方式是 AIDL ,这方面在网上有很多资料,最简单的方式就是自己写个 aidl 文件自动生成一个 Java 类,然后去查看这个Java类的每个方法和变量,然后再去看四大组件,其实都是跟 AIDL 差不多的实现方式。

其次,是 App 打包的流程。代码写完了,执行一次打包操作,中途经历了资源打包、 Dex 生成、签名等过程。其中最重要的就是资源的打包,即 AAPT 这一步,如果宿主和插件的资源id冲突,一种解决办法就是在这里做修改。

第三, App 在手机上的安装流程也很重要。熟悉安装流程不仅对插件化有帮助,在遇到安装 Bug 的时候也非常重要。手机安装 App 的时候,经常会有下载异常,提示资源包不能解析,这时需要知道安装 App 的这段代码在什么地方,这只是第一步。第二步需要知道, App 下载到本地后,具体要做哪些事情。手机有些目录不能访问, App 下载到本地之后,放到哪个目录下,然后会生成哪些文件。插件化有个增量更新的概念,如何下载一个增量包,从本地具体哪个位置取出一个包,这个包的具体命名规则是什么,等等。这些细节都必须要清楚明白。

第四,是 App 的启动流程。 Activity 启动有几种方式?一种是写一个 startActivity ,第二种是点击手机 App ,通过手机系统里的 Launcher 机制,启动 App 里默认的 Activity 。通常, App 开发人员喜闻乐见的方式是第二种。那么第一种方式的启动原理是什么呢?另外,启动的时候,Main 函数在哪里?这个 Main 函数的位置很重要,我们可以对它所在的类做修改,从而实现插件化。

第五点更重要,做 Android 插件化需要控制两个地方。首先是插件 Dex 的加载,如何把插件 Dex 中的类加载到内存?另外是资源加载的问题。插件可能是 Apk 也可能是 so 格式,不管哪一种,都不会生成 R.id ,从而没办法使用。这个问题有好几种解决方案。一种是是重写 Context 的 getAsset 、 getResource 之类的方法,偷换概念,让插件读取插件里的资源,但缺点就是宿主和插件的资源 id 会冲突,需要重写 AAPT 。另一种是重写 AMS中保存的插件列表,从而让宿主和插件分别去加载各自的资源而不会冲突。第三种方法,就是打包后,执行一个脚本,修改生成包中资源id。

第六点,在实施插件化后,如何解决不同插件的开发人员的工作区问题。比如,插件1和插件2,需要分别下载哪些代码,如何独立运行?就像机票和火车票,如何只运行自己的插件,而不运行别人的插件?这是协同工作的问题。火车票和机票,这两个 Android 团队的各自工作区是不一样的,这时候就要用到 Gradle 脚本了,每个项目分别有各自的仓库,有各自不同的打包脚本,只需要把自己的插件跟宿主项目一起打包运行起来,而不用引入其他插件,还有更厉害的是,也可以把自己的插件当作一个 App 来打包并运行。

上面介绍了插件化的入门知识,一共六点,每一点都需要花大量时间去理解。否则,在面对插件化项目的时候,很多地方你会一头雾水。而只要理解了这六点核心,一切可迎刃而解。

实现原理

在Android中应用插件化技术,其实也就是动态加载的过程,分为以下几步:

  • 把可执行文件( .so/dex/jar/apk 等)拷贝到应用 APP 内部。

  • 加载可执行文件,更换静态资源

  • 调用具体的方法执行业务逻辑

Android 项目中,动态加载技术按照加载的可执行文件的不同大致可以分为两种:

  • 动态加载 .so 库

  • 动态加载 dex/jar/apk文件(现在动态加载普遍说的是这种)

第一点, Android 中 NDK 中其实就使用了动态加载,动态加载 .so 库并通过 JNI 调用其封装好的方法。后者一般是由 C/C++ 编译而成,运行在 Native 层,效率会比执行在虚拟机层的 Java 代码高很多,所以 Android 中经常通过动态加载 .so 库来完成一些对性能比较有需求的工作(比如 Bitmap 的解码、图片高斯模糊处理等)。此外,由于 .so 库是由 C/C++ 编译而来的,只能被反编译成汇编代码,相比中 dex 文件反编译得到的 Smali 代码更难被破解,因此 .so 库也可以被用于安全领域。

其二,“基于 ClassLoader 的动态加载 dex/jar/apk 文件”,就是我们指在 Android 中 动态加载由 Java 代码编译而来的 dex 包并执行其中的代码逻辑,这是常规 Android 开发比较少用到的一种技术,目前说的动态加载指的就是这种。

Android 项目中,所有 Java 代码都会被编译成 dex 文件,Android 应用运行时,就是通过执行 dex 文件里的业务代码逻辑来工作的。使用动态加载技术可以在 Android 应用运行时加载外部的 dex 文件,而通过网络下载新的 dex 文件并替换原有的 dex 文件就可以达到不安装新 APK 文件就升级应用(改变代码逻辑)的目的。

尾声

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

最后想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。

当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。

进阶学习视频

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)


《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
汇总。)

[外链图片转存中…(img-ngqWou10-1715417527877)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 28
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面我会使用 SQL 语句来实现这些操作: 1. 建立一个名为职工的表,它包含编号、姓名、性别、年龄、工资、职称这六个字段。 ```sql CREATE TABLE 职工 ( 编号 INT PRIMARY KEY, 姓名 VARCHAR(20), 性别 VARCHAR(4), 年龄 INT, 工资 DECIMAL(10, 2), 职称 VARCHAR(20) ); ``` 2. 向职工表中插入三条记录,如上表所示;并查询所有职工信息,输出到控制台。 ```sql INSERT INTO 职工 VALUES (1001, '丁卫国', '男', 25, 2500, '助工'); INSERT INTO 职工 VALUES (1002, '张小华', '女', 30, 1000, '工程师'); INSERT INTO 职工 VALUES (1003, '宁涛', '男', 50, 600, '高工'); SELECT * FROM 职工; ``` 查询结果如下: ``` 编号 姓名 性别 年龄 工资 职称 1001 丁卫国 男 25 2500.00 助工 1002 张小华 女 30 1000.00 工程师 1003 宁涛 男 50 600.00 高工 ``` 3. 将年龄在45岁以上的员工工资增加15%,其他人增加10%,存入原表中,并查询更新后的所有员工信息,输出到控制台。 ```sql UPDATE 职工 SET 工资 = 工资 * 1.15 WHERE 年龄 > 45; UPDATE 职工 SET 工资 = 工资 * 1.10 WHERE 年龄 <= 45; SELECT * FROM 职工; ``` 查询结果如下: ``` 编号 姓名 性别 年龄 工资 职称 1001 丁卫国 男 25 2750.00 助工 1002 张小华 女 30 1100.00 工程师 1003 宁涛 男 50 690.00 高工 ``` 4. 删除工资超过1500的员工记录,并将每条记录按照工资由大到小的顺序显示输出到控制台。 ```sql DELETE FROM 职工 WHERE 工资 > 1500; SELECT * FROM 职工 ORDER BY 工资 DESC; ``` 查询结果如下: ``` 编号 姓名 性别 年龄 工资 职称 1002 张小华 女 30 1100.00 工程师 1003 宁涛 男 50 690.00 高工 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值