Skip to content

开篇词:跳出舒适区,走在行业前端

你好,我是姜新星,一个深耕 Andorid 领域的老工程师。


记得 2010 年毕业典礼上,某位老师说"你们是最幸福的一届毕业生,正好赶上中国移动互联网的元年",虽然当时对这句话还是懵懵懂懂的状态,但还是义无反顾地投入了 Android 开发这波浪潮。"一厘米宽,一公里深",一干就是十年。


在这期间,我先后任职于斐讯、一号药店、360、英孚教育等多家公司,参与过 Launcher 定制化、ROM 定制、在线教育、电商等众多领域的开发工作,算是见证了国内智能手机厮杀的前世今生,也对 Android 开发有了一些独到的见解。

面试,是技术深度与广度的试金石

如今在英孚教育,因为工作需要,我经常需要面试一些 Android 工程师,过程中发现很多人对于 Android 知识的掌握还是多浮于表面,对一些技术点只停留在"使用过"甚至是"听说过"的阶段,这其中甚至不乏一些工作 5 年以上的 Android 工程师。


  • 几乎所有的 Android 开发者都使用过 String,但当我问"String 的最大长度是多少"时,鲜有人能够完全答对,更何谈如何去解决"字符串长度过长"的异常问题。

  • 有人会很费解,为什么面试官会问到如何自定义 Java 类加载器的问题,难道双亲委派机制不是 JVM 内部实现的吗?但殊不知,不理解 JVM 的底层原理,就谈不上自定义类加载器,更不用说实现热修复、组件化开发了。

  • 还有一些面试者,会在面试前恶补 JVM 知识,对 Java垃圾回收(GC)也能够侃侃而谈,甚至还能够现场说出一些 JVM 调优参数。但是,如果你再展开提问"Android 中 Dalvik 和 ART 的回收机制有何不同",可能就瞬间"宕机"了。

  • 很多人都会在简历中标识自己"精通多线程",但是扪心自问一下这几个问题能答上来吗:线程中的"工作内存"指的是什么? 为什么会导致线程安全问题?


当然,也有很多求职者抱怨大厂"面试造火箭,工作拧螺丝",但实际上,面试中的大多数问题都是在全方位地考察你对技术的理解深度,以及解决问题的能力。你看似无理甚至无用的问题,比如"是否写过自定义 Gradle 插件?",其实是面试官想借此看看你对 Gradle 的理解情况和掌握程度,进而引申到你对 Android 编译打包流程的理解。在熟知编译打包流程的前提下,你才会深谙 APK 深度瘦身的原理和过程。


听起来像是各种套路,但是技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面。


如今,国内移动互联网的红利期已经过去,Android 开发工程师也从最初的一人难求,到现在的一个岗位百人竞争,僧多粥少的情况直接导致整个行业对求职者的要求越来越高。可以说,初中级工程师基本已无立足之地,即使高级工程师也经常在面试中碰钉子。


此外,随着 Android 开发越来越规范,国内工程师的素质,以及用户对产品的要求也越来越高。这也间接导致我们对研发项目的质量要求到了近乎苛刻的地步,内存优化、UI 卡顿优化、App 崩溃监控等性能调优也逐渐成了人手必备的技能。工作之余,难免让我们感慨学无止境,以及 Android 开发也是水深不见底。

跳出舒适区,走在行业前端

我的第一份工作是在斐讯这家专攻通信设备的公司,我当时在智能手机研发终端部门,负责 Android 2.2 系统中 Launcher2 的定制化。随后 Android 系统不断升级,从 2.X 系统搭配 Marvel 芯片到 4.X 系统搭配高通芯片,从 Launcher2 到 Launcher3,再到后来的 Framework,这让我对 Android 系统底层源码有了深入的理解,也为后来掌握整个 Android 生态知识体系打下了坚实的基础。


后来,国内移动互联网行业如雨后春笋般发展,Android App 的开发需求也越来越多。因为ROM定制化开发还是有一定的局限性,为了拓宽自己的职业发展方向,以及对互联网 App 开发的一丝好奇,让我萌生了从厂商出来看看世界的想法。


刚进入 App 开发领域,我发现和系统源码开发完全不一样,互联网 App 开发需要掌握各种架构和第三方框架,比如 MVP、MVVM、Volley、Picasso、GreenDao 等。而这些开源库框架的实现或者理念,对于那时的我来说完全是新事物。意识到自己的不足之后,我开始疯狂恶补各种开源库的实现原理,比较各个"轮子"之间的优缺点,同时也尝试自己去写开源控件(一篇往期文章,参见"自定义ViewGroup实现仿淘宝的商品详情页")。


这个过程,让我慢慢发现了自己的一些优势。在与同事吃饭聊天时,每当聊到某一个 Bug 产生的原因时,我总能从 Framework 层源码的角度分析根本原因,并指出客户端需要在哪些方面做出适配,这对只做过 App 开发的工程师来说是一个比较大的瓶颈。比如,我在网上分享过如何在 Activity 中使用 Theme.AppCompat 主题(You need touse a Theme.AppCompat theme with this activity) 的相关解决思路,网上大多对这个问题的解决办法都是让 MainActivity 继承自 Activity 即可,但是这种解决思路有极大的局限性,且不说改为 Activity 是否适合每家公司的项目,即使免为其难全部改为 Activity,也会导致无法兼容老版本的样式,并且相当于间接放弃了 Android 5.0 之后的 Material Design 效果。因此只有了解源码,并从源码的角度分析,才会找到更完美的解决方案


记得是在一次代表公司参加上海开发者讨论会的时候,我听到了很多之前不曾太关注的名词,比如组件化开发、性能监控、Android 演进式架构等等,仿佛打开了我通往 Android 世界的另一扇大门,原来 Android 开发并不是单纯的实现各种业务逻辑,而是一整套架构的搭建,比如自动化测试、性能监控、组件解耦等。回到公司之后,我与同事讨论的话题不再是某某公司新开发的框架,而是变成了"App 的崩溃率是多少?""埋点怎么做?""架构中基础组件之间通信是怎么玩的?"等等。


而当我尝试去搭建这一套基础架构时,发现自己虽然做了多年的 Android 开发,但是对于 Java 虚拟机、Dalvik 字节码的理解远远不够,所以在实现性能监控、组件化/插件化、编译插桩时举步维艰,深深体会到了技能瓶颈的限制。幸好公司给予我足够的信任和包容,我开始深挖 Java 虚拟机、Linux 系统、Android 操作系统等各种知识,尝试新的玩法,最终成功搭建了一套自己的性能检测流程、线上监控系统,以及完整的无痕埋点实现机制。

课程设计

鉴于以上原因,我一直在寻找一个可以分享过往经验的出口。


在这个专栏中,我希望为你理清 Android 面试的主线思路,通过详解各大互联网公司的常见面试题,从面试的角度去展开介绍某一知识点,以及该知识点在项目中的使用,并在此过程中帮你梳理和建立 Android 开发的知识体系。


因此,无论是你短期内想提升 Android 内功实力,突破自己工作中的能力瓶颈,还是准备参加 Android 面试,都会在这个课程中有所收获。


这个课程,我根据面试时经常被问到的几个方向,划分了 4 个模块来展开:

  • JVM 必知 **必会:**通过介绍 JVM 和 DVM ,使你对 Java 字节码与 Dalvik 字节码的执行机制有一定的理解。

  • Android 核心 **术:**介绍 Android 开发中常用的核心技术,比如自定义 View、Handler,以及一些开源框架的原理实现。

  • 源码分析 **:**通过剖析部分 Android Framework 源码,使你对 Activity 启动、APK 安装过程等流程了然于胸。

  • 常见问题 **剖析:**介绍一些项目中常见的疑难问题,使你能够对现有项目做出合理并迅速的重构优化。


为便于你理解,我会采用"知识点 + 项目实践"的讲解方式,侧重总结工作上的实践经验,并和你分享一些疑难问题的解决思路,让你在以后的工作中,能够有方法论的指导。


此外,技术内容终归过于抽象,为了方便你更直观、方便地理解课程内容,我会借助大量图示来解释某一原理或者工作流程,并在专栏中穿插大量诸如 ASMDemo 、DexClassLoaderHotFix 等代码案例,来一步步告诉你如何将学到的底层原理应用到实际项目中。


写在最后

Android 工程师的竞争环境越来越激烈,但 Andorid 开发仍然是一个刚需的工种,行业对人才的需求从未终止,但与此同时也对我们提出了更高的要求。如果你仍然只是在日常开发过程中复制粘贴,或者仍以完成一个项目需求为唯一目的,只是掌握了如何去调用某个 API 或者数据结构来实现某个功能,已经不能算是合格的工程师了。


对于 Android 开发者来说,要成为优秀的 Android 开发工程师,不只能够让你在工作中更加游刃有余,同样会让你在职业发展中面临更多优质的机遇。而一个初中级 Android 工程师在通往高级甚至是资深工程师的发展过程中,我认为这个课程中超过 90% 的内容都是你必须掌握,且无法绕过的。


挑战中,总是蕴藏着机遇;大浪淘沙,留下来的必定都是顶尖人才。希望我能够在这里帮到你。当然,技术首先在于学习和理解,更关键地在于后续的实践应用,也希望你能将课程所学不断应用和反馈到你的工作实践之中,并欢迎和我分享你的成长。