本书在京东购买地址:https://item.jd.com/31178047689.html
本书Q群:389329264
(一)这是一本什么书
如果只把本书当作纯粹介绍Android插件化技术的书籍,那就大错特错了。
本书在研究Android插件化之余,还详细介绍了Android系统的底层知识,包括Binder和AIDL的原理、四大组件的原理、App的安装和启动流程、Context和ClassLoader的家族史。没有罗列大量的Android系统中的源码,而是以一张张UML图,把这些知识串起来。
本书详细介绍了Android中的资源机制,包括aapt命令的原理,resource文件的组成,以及public.xml的使用方式,顺带还提及了如何自定义一个Gradle插件化。
此外,本书还介绍了so的加载原理,尤其是动态加载so的技术,可以帮助app进行瘦身;探讨了H5降级技术,可以实现任何一个原生页面和H5页面的互换,介绍了反射技术,以及jOOR这个有趣的开源框架;介绍了Android中的动态代理技术Proxy.newProxyInstance方法。
如果读者能坚持把这本书从头到尾读完,那么不光掌握了插件化技术,同时也把上述所有这些知识点全都系统的学习了一遍。也许Android插件化会随着Google的限制而有所变化甚至消亡,但我在本书中介绍的其他知识,仍然是大有用武之处的,这也是本书的特色。
(二)如何面对Android P的限制
写作这本书的时候,Google推出了Android P preview的操作系统,会限制对@hide api的反射调用。目前会通过log发出警告,用户代码仍然能够获取到正确的Method或Field,在后续版本中获取到的Method或Field极有可能为空。
但是道高一尺,魔高一丈。Google对这次限制,很快就被技术geek们绕过去了[1],有两种解决方法:
1)把通过反射调用的系统内部类,改为直接调用。
具体操作办法是,在Android项目中新建一个库,把要反射的类的方法和字段,复制一份到这个库中,App对这个库的引用关系设置为provided。那么我们就可以在App中直接调用这个类和方法,同时,在编译的时候,又不会把这些类包含到Apk中。
其实早在2015年,hoxkx就在他的插件化框架中实现了这种技术[2]。
但是这种解决方案,仅限于Android系统中标记为public的方法和字段,对于protected和private就无能为力了。
2)类的每个方法和字段,都有一个标记,表明它是不是hide类型的。我们只要在jni层,把这个标记改为不是hide的,就可以绕过检查了。
然而,魔高一丈,道高一丈二。Google在Android P的正式版中势必会推出更严厉的限制方案,到时候,又会有新的解决方案面世,让我们拭目以待。
其实,作为开发者而言,是不希望看到开发者们和Google之间的技术对抗的,这是毫无意义的内耗。,泛滥成灾的篡改,导致了App大量的崩溃,Google实在看不下去了,所以才搞出这套限制方案;另一方面,插件化技术是刚需,尤其在中国的互联网行业,App崩溃了影响生意,会导致绩效奖金都被扣光,所以开发者才会不惜一切代价走插件化这条路。
再回到限制方案来,Google也不是清一色不要开发者使用系统底层的标记为hide的api,而是推出了一组黑灰名单,如下所示:
名单 |
影响 |
light-greylist 浅灰名单 |
仅打印警告日志,Google尽可能在未来版本提供 public API |
dark-greylist 深灰名单 |
第三方App不能访问,开发者可以申请把这份清单中的某些api加入到浅灰名单 |
blacklist 黑名单 |
第三方App不能访问 |
所以,另一种应对策略是,在插件化中使用浅灰名单中的api,比如说ActivityThread的currentActivityThread方法。
Google的这组清单,还在持续调整中,据我所知,给各大手机厂商的清单,就和他在社区中发布的清单,略有出入。在Android P的正式版本中,这份清单会最终确定下来。所以现在中国的各个插件化框架的开发人员,都在等Android P的正式版本发布后再指定相应的策略。留给中国队的时间不多了。
(三)写这本书的来龙去脉
这是一本酝酿了3年的书。
早在2015年Android插件化技术百家争鸣时,我就筹划写这方面的书了。但当时积累的技术不够,就没写出来。我当时在一场技术大会上有个《Android插件化从入门到放弃》的演讲,四十五分钟只能介绍插件化的皮毛。后来这个演讲内容被整理成文章发布到网上,流传很广。
2017年1月,有企业要我去讲2天Android插件化的技术。为此,我花了一个月时间,准备了四十多个例子。这是第一次的素材积累。
2017年6月,我在腾讯课堂做线上培训,为了宣传推广我的课程,我写了一套文章《写给Android App开发人员看的Android底层知识》,共计8篇,没列太多代码,完全以UML图的方式,向读者普及Binder、AIDL、四大组件、AMS、PMS的知识。本书的第2章,就是在这8篇文章的基础之上进行扩充的。
2018年1月低,我父亲住院一周。我当时在医院每天晚上值班。老爷子半夜打呼噜,吵的我睡不着,虽然事后我才知道,我睡着了打呼噜声音比他还大。半夜睡不着,就开始了本书的写作,每晚坚持写到凌晨两三点。直到父亲出院,这本书写了将近五分之一。
碰巧的是,这一年5月底,我结婚。所以我必须在5月初,完成这本书的一稿,为此,我宅在家里整整写了3个月,拼了老命,才赶在这个时间点交稿。
仅以此书作为新婚礼物献给我亲爱的老婆,感谢你的理解,这本书才得以面世。
(四)这两年我在忙些什么?
写完《App研发录》后不久,大约是2016年5月,我就从一线互联网公司出来,开始了长达两年的App技术培训工作。
一改之前十几年在办公室闷头研究技术的工作方式,而是在全中国飞来飞去,给各大国企、传统公司、手机商的Android和iOS团队进行培训。这两年去过了近百家公司,谈一谈我的切身感受。
App技术人员以一种金字塔型的方式存在,在金子塔尖的,自然是那些一线互联网的开发人员,他们掌握Android和iOS最先进的技术,比如说组件化、插件化等等这些技术,但这些人毕竟是少数,一线互联网也就是那十几家,他们的技术人员加在一起,也就是三两千人;而位于金字塔底端的开发人员则是大多数,他们大都位于创业公司或者传统行业,相应的App侧重于业务的实现,对App的高尖端技术,用的不多,自然也谈不上掌握。
另一方面,我还在腾讯课堂讲了几个月App开发课程,认识了很多学员,有几千粉丝。他们也有类似的苦恼。
写作这本书,则是向广大Android开发人员普及插件化技术。
(五)这本书讲些什么
战战兢兢写下这本书,十几万言。
插件化千头万绪,流派众多。凭借一己之力,并不能覆盖其所有。我这本书从最基本的原理讲起,配合以大量的例子,能帮助一个完全不懂Android插件化的技术小白,升级为一个精通这本技术的高手。
面对业内各种成熟的插件化框架,我只选取了具有代表意义的DroidPlugin、DL、Small和Zeus进行介绍。这几个框架基本覆盖了插件化编程的所有思想,而且非常简单,像Zeus就只有11个类,就支撑起掌阅App的插件化。
而对于后期推出的VirtualApk、Atlas、Replugin,我在本书中并没有章节去介绍,主要是因为这些框架都是大块头,代码量很多,我没有精力再去研究和学习了。但这些企业级插件化框架,所用的技术,本书都有涉及。
(六)本书的结构。
全书分为三大部分。
第1部分包括第1章到第5章,是Android插件化编程的准备知识。
第2部分包括第6章到第16章,介绍了插件化编程的各种解决方案。
第3部分包括第17章到第21章,介绍插件化编程的周边技术。
接下来简要介绍一下本书各章的内容。
第1章介绍的是Android插件化的历史,当作小说来读,茶余饭后,地铁站中,这一章是最容易看懂的。
第2章介绍Android底层知识,涉及到那些与Android插件化相关的知识,比如说Binder和AIDL,比如说Android App的安装流程和启动流程,比如说ActivityThread,比如说LoadedApk,比如说Android四大组件的运行原理。这一章篇幅较多,需要仔细研读。其中,讲到一个音乐播放器的例子,帮助大家更加深刻的认识Android的四大组件。
第3章讲反射,详细介绍了构造函数、方法、字段、泛型的反射语法。本章介绍了Java领域很火的一个开源库jOOR,可惜,它对Android的支持并不是很好,所以本章还介绍了我们自己封装的RefInvoke类,这个类将贯穿本书,基本上所有源码例子都会使用到它。
第4章讲代理模式。这个模式在Android中最著名的实现就是Proxy.newProxyInstance方法。基于此,我们Hook了AMS和PMS中的一些方法。
第5章是第4章的延续,仍然是基于Proxy.newProxyInstance方法,Hook了Activity的启动流程,从而可以启动一个没有在AndroidManifest中声明的Activity,这是插件化的核心技术之一。
第6章介绍了如何加载插件App,以及如何对插件化项目的宿主App和插件App同时进行调试。说到插件化编程,就离不开面向接口编程的思想,本章也花了很多笔墨介绍这个思想,以及具体的代码实现。
第7章介绍了资源的加载机制,包括AssetManager和Resources。本章给出了资源的插件化解决方案,从而为Activity的插件化铺平了道路。。本章还介绍了换肤技术的插件化实现。
第8章介绍了最简单的插件化解决方案,通过在宿主App的AndroidManifest中事先声明插件中的四大组件。为了能让宿主App随意加载插件的类,本章介绍了合并dex的技术方案。
第9章到第12章介绍了Android四大组件的插件化解决方案。四大组件的生命周期各不相同,所以它们各自的插件化解决方案也都不同。
第13章、第14章介绍了Android插件化的静态代理的解决方案。这是一种“牵线木偶”的思想,我们不用Hook太多Android系统底层的代码。
第15章再次讲到资源,这次要解决的是宿主和多个插件的资源id值冲突的问题。有多种解决方案,本章都会有介绍,有思想的分析,有具体的代码示例。
第16章介绍一种古老的插件化解决方案,通过动态替换Fragment的方式。
第17章介绍了介绍了App的降级解决方案。一旦插件化方案不可用,那么我们仍然可以使用H5,来替换任何一个App原生页面。
第18章介绍了插件的混淆技术。有时候宿主App和插件App都会引用MyPluginLibrary这个类库,这个公用类库是否要混淆,相应的有两种不同的混淆方案。
第19章介绍了增量更新技术。这是插件化必备的技术,从而保证插件的升级,不需要从服务器下载太大的包。
第20章介绍了so的插件化解决方案。本章详细介绍了so的加载原理,以及从服务器动态加载so的方案,基于此,有两种so的插件化解决方案。
第21章作为整本书的结尾,系统总结了Android插件化的各种解决方案。Android插件化技术千头万绪,本书花了将近二十章的篇幅,系统介绍这些技术的思想和实现,如果读者能坚持读到这最后一章,本章可以帮助读者巩固这些知识。
(七)名词解释
本书中有很多专业术语,对于刚接触Android插件化的读者,可以不容易理解。有一些专业术语,还有别称或者简称,我在这里罗列出最常见的一些术语:
HostApp,本书中有时也写作“宿主App”。用于承载各种插件App,是最终发版的App。我们从Android市场上下载的,都是HostApp。
Plugin,本书中有时也写作“插件”、“插件App”。
Receiver,是BroadcastReceiver的简称,Android四大组件之一。
AndroidManifest,也就是AndroidManifest.xml。
Hook,在本书中有时也写作“篡改”,就是使用反射修改Android系统底层的方法和字段。
AMS,是ActivityManagerService的简称,在App运行时和四大组件进行通信。
PMS,是PackageManagerService的简称,用于App的安装和解析。
(八)关于本书的源码
本书有70多个源码例子,请参见附录2,列出了所有的源码的地址和对应的章节。此外,在本书的正文中,在用到了源码的章节处,我也标注出相应的代码例子的地址。
(九)感谢
几乎所有的书都千篇一律的感谢父母妻子、同事领导、图书编辑,却不写为什么要感谢他们。
我这里一定要把感谢的理由说清楚。
首先,感谢我那古灵精怪的老婆郭曼云。谢谢她在我人生迷惘的时候及时出现,陪我玩王者荣耀,带我骑小黄车去散心,看电影时一起八卦剧情然后被坐在旁边的观众出声制止,头疼去医院看神经内科后从此她在我眼中便成为了深井冰。又比如说,每天要我做不一样的饭菜给她吃,把我锻炼成厨房小能手,我现在已经习惯于每天傍晚五点半就放下手中所有的活儿,愉快的投入买菜做饭的工作。我时常自诩为还没遇到刘备的诸葛亮,如果真是那样,那么她命中注定就是那个丑丑的黄月英。
其次,感谢张勇、任玉刚、罗迪、黄剑、林光亮、邓凡平、王尧波、田维术这些Android领域的朋友,我在写作这本书的时候,经常会遇到各种疑惑,每次问到他们,都会不厌其烦的给我详细的解答。
在这里,尤其感谢田维术,他的技术博客(weishu.me)对我的影响很大,可惜没写完,只讲了Binder原理和四大组件的插件化方案。本书的部分章节,参考了他的博客文章,对他提供的一些代码例子,进行了二次加工。经过他本人同意后,收入我这本书中。代码中的很多类上,都标注了作者是weishu,以表达对他的感谢。
第三,感谢任正浩、霹雳娇娃、何以笙、韦辰这群狐朋狗友的陪伴,在我从互联网出来转型做App技术培训的过程中,初期没啥生意,整理了半年ppt教程后才开始陆陆续续的接单子,在这半年时间里,我就跟这帮学弟学妹厮混在一起,爬山、撕名牌、唱K、密室逃脱、狼人杀,还有一阵时间沉迷于你画我猜,四个人玩到凌晨五点。那是我最惬意的一段时光。
最后,感谢我爸我妈以及咱爸咱妈。你们的女儿我一定照顾好。虽然北京天津那么近,很抱歉还是不能常回家看看,我永远是那么忙,忙着去追求事业的成功,距离财务自由还很远,但是我一直在努力。
第三,感谢曹洪伟等21位社区朋友的辛勤劳动,把这本书翻译为英文,限于篇幅,这里就不一一列举了。接下来这本书的英文版本会在国外网站社区逐篇发布以及出版成书,让全世界的Android开发人员看到中国工程师们的智慧结晶。
[1] 详细内容,请参见田维术的文章:http://weishu.me/2018/06/07/free-reflection-above-android-p/
[2] 项目地址参见:https://github.com/houkx/android-pluginmgr