组件的生命周期是一个抽象的状态机。这里的抽象的意思是指,这些状态机的状态是预先定义好的,它们之间的转换条件也是定义好的。但是这些定义是不完整的。你需要去实现缺少的部分,使他们可以正常工作。这些缺少的部分是这些组件方法的子集,我们称其为“生命周期回调”,除了状态机本身之外,这些生命周期回调中,也有很多隐式的限制和约束。这些限制有些写在了文档中,而有些却并没有记录。
生命周期到底有多复杂?我们先来看一下这张图 (它有点不完整,还有点过时)。这张图,看起来有点可怕。不过,你也不要慌,大多数 Andorid 开发者都搞不明白这个图。事实上,即使 Google 的 Android 开发者也搞不明白生命周期的问题。Google 在发布 Lifecycle 组件的时候,里面引入了一些有关 Fragment 的 bug, 直到后续的新版本发布了才得以修复。
虽然现在你不需要完全掌握 Android 的生命周期,但是你必须要知道一些重要的细节。否则,你的代码会变得混乱不堪,并且容易出现一系列难以解决的问题。我写了两篇文章 Activity 生命周期与 Fragment 生命周期 ,描述了生命周期的细节。当你不知道如何使用 onStart 和 onResume 时,你可以去看看这两篇文章。
当你掌握了生命周期的基础知识,你可以去看看 Gabor Varadi 写的 Android 开发的十宗罪 ,这篇文章,列举出了大多数开发者都会犯的错误。这些错误大多数都与生命周期有关。
顺便说一下,在面试中,生命周期相关的问题也会被经常问到。这也是你必须好好学习生命周期的原因。
- Context
在每一个 Android 应用程序中,都有一个或多个上下文对象。
和生命周期一样,它也很难被解释。它就像是一个“上帝类“一样,它有非常多的能力。我们很难用一两句话就把它描述清楚。尽管如此,理解 Context 职责和不同 Context 之前的区别也是非常重要的。
本文中,没有更多关于 Context 的内容,我建议你去读一下 StackOverflow 中关于 《What is ‘Context’ on Android?》 的回答和这个回答的内容.
- UI 线程
每一个 Android 应用程序都有一个特殊的线程 —— UI 线程。这一个线程在屏幕上绘制出 UI 页面。如果你让 UI 线程超负荷运行,你的应用程序将会变得卡顿,不响应。在极端情况下,UI 线程中的错误会导致整个应用程序出错(至少看起来像是出错了)。
如果你想详细了解线程背后的机制原理,你可以去看这个视频,视频中详细解释了 Android 中的多线程,包含 UI 线程的相关细节和可能存在的问题。
- 逻辑拆分
从整体上说,Android 框架的代码很不“整洁”。它包含着很多的上帝类,这些类中,每一个有数千行代码,并且我们还必须去扩展这些类,才能让我们的应用程序运行起来。在多数情况下,不管是 Application, Activity ,Fragments 还是 Service,我们都是在一个很大的类中,做很多的事情。
虽然在 Andorid 开发中,这是一个常见的做法,但这样子做并不利于长期维护我们的代码逻辑。因此我建议,要尽可能的注意这个问题,多找机会去重构代码,将逻辑拆分到独立的类中去。
说实话,我现在并不认为,一个初级开发者可以对架构和设计做出太多的改善工作。正确的封装代码逻辑,提取出有意义的类,都需要一些开发经验。当然,我也不希望你不去思考代码拆分,你可以做一些力所能及的事情,避免出现不可控的情况(例如,一个 Activity 中写了超过 5000 行代码)。
刚开始,你可以尝试拆分这篇文章中描述的与 Context 有关的逻辑。
2-4 年开发经验
当你在你的职业生涯中工作几年,你变成经验丰富的 Android 开发者,通过研究和学习,你可以很轻松的实现一些非专业化的功能。那下一步,你该做什么?
我认为,在这个时候,你已经很熟悉 Android 框架的基础知识了,可以尝试去学习更高层次的技能。这些技能不局限于 Android,它们是一些通用的软件开发的技能。具体来说,你可以研究以下主题:
- 依赖注入
依赖注入是一个关注结构分离的设计模式。它主要是用来进行分离应用程序的两个功能:应用程序和核心功能、核心功能组件实现之间的链接。
从某些方面来说,实现了依赖注入的代码库就好你一个计算机:依赖注入的基础库就像是主板一样,而其他的功能组件就好像是 CPU、内存、外设等。只要你的代码中实现了依赖注入,你就可以很方便的插入新功能,并且可以很容易的重用其它组件的功能,也可以很方便的使用新组件的功能。虽然这个比喻有点夸张,但是在我看来,它也确实很好的反映了依赖注入背后的思想。
不幸的是,现在关于依赖注入的文章,很多都存在误解,这给初学者带来很多干扰。因此,如果你想学习依赖注入,我建议你读一下这篇文章,本文中,我分析了众多依赖注入的“神话“。
- UI 分离
由于 Android 框架本身的架构,造成了我们在开发的过程中,使用户页面与应用程序中的其它逻辑耦合在一起。几乎所有的 Android 初学者都会这样。这种耦合会导致我们写一个很大的类,这个类里面有应用程序的 UI 绘制、网络处理、多线程处理、应用业务逻辑等。
根据我的经验,UI 逻辑与其它逻辑耦合在一起,会导致代码的可维护性越来越差,迟早会使用代码变得难以理解,无法阅读。到最后,可能会因为功能上的一点小变化,引起很大的副作用。
要将 UI 逻辑与其它逻辑进行分离,可以用使用 Model- View - X 的架构模式。例如: Model-View-Contoller(MVC)、Model-View-Presenter(MVP)、Model-View=ViewModel(MVVM)。这些架构模式都属于同一类架构,当然,这一类架构不仅仅包含列举的这几个,还有其它的架构模式。在这里,为了更方便的描述这一类架构模式,我把他们统称为 MVx 模式。
当你在学习 MVx 模式的时候,请记住,这些都不是架构,而是一种架构模式。这些架构模式仅用于 UI 展示逻辑。因此仅仅使用 MVx 并不能给你一个好的架构,要有一个好的架构,你还需要在其它方面做出更多的努力才能实现。
- 多线程
有经验的 Android 开发者都会了解多线程,并且了解他们对应用程序的影响。你也许会说,我精通 AsyncTask、RxJava、协程等。我想表达的多线程不是你理解的这个。会使用多线程框架并不等同于理解多线程。
举个例子,众多 Android 开发者都认为,使用 AsyncTask 会导致内存泄漏。这个观点来自 Android Studio 默认的多线程 lint 规则中。既然如此,那这个观点就是对的了吗?很不幸,这个观点是错误的。在这里,我不讲解它们的细节,你可以读一下这篇文章,里面有很多关于 AsyncTask 的内容。
我认为要理解多线程程,就必须可以使用任何多线程框架,甚至是基于基础的 Thread ,都可以写出正确的并发代码。要实现这个目标,你不仅仅需要知道你喜欢的多线程库的 API,你还需要理解多线程的细节。这些多线程库虽然好用,但如果你不理解多线程的基础细节,那么你的应用程序出现多线程的问题只是时间问题。
如果你想学习多线程,从这个视频 开始,视频中讲解了所有 Android 开发人员都需要知道的基本概念与原理。
- 自动化测试
据我所知,很多 Android 项目,都没有使用任何的自动化测试。在使用自动化测试的项目中,大多数也是 QA 人员使用 Appium 之类的工具来完成的。这是整个 Android 行业的现状,非常可悲。之所以没有自动化测试,这个问题可以追溯到 Android 起源,Google 也在很长一段时间里,没有关注过第三方应用的自动化测试。
现如今,有单元测试和 UI 自动化测试经验的开发者需求量很大。即使你到一家没有使用过任何自动化测试的公司去面试,如果你说你会自动化测试,就会给你的面试加分。反之,如果你去的是一个广泛使用自动化测试的公司,你没有自动化测试的技能,这会给你面试减分,处于劣势。
因此,我建议每一个 Android 开发者都去学习一下自动化测试的相关知识。就个人
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
而言,我更喜欢单元测试。而一些开发者喜欢 UI 自动化测试。所以,可以选择一个你更感兴趣的技术,尝试一下。
4 年以上经验
如果你对 Android 已经有了非常丰富的开发经验,那么,是时候学习一些“元”技能了,并且在特定领域进行深度研究。在我看来,以下技能对专业的开发人员来说,都是非常不错的方向。
- 技术方案评估
如果你还没有做过这件事情,那么现在是时候开始做了。每一个重要的技术决定,都需要进行评估、权衡。有时候,这种决定带来的结果非常好,立竿见影。但是大多数时候,并非总是能够立竿见影,看到效果。通常情况下,需要决策的范围越大,所涉及到的评估范围就越大,除了可以简单进行决策的事情,还有很多可评估项都是非常抽象,短时间内根本看不到结果的。
在自己丰富的经验水平下,面对众多选择,你至少应该知道如何找到取舍。如果你能对技术方案评估提供有用的建议,你就非常优秀了。技术方案评估权衡这是一项非常复杂的技能。通常,在与其它开发者、项目经理甚至是其它部门员工讨论的时候,你能找到折中方案,就能进行方案评估。因此,在大数情况下,你只需要掌握评估方案的能力就够了。
那我们所说的“技术方案的评估”到底是什么意思?说实话,很难具体说明它是什么。不过,我们可以提供一些反例,来解释为什么不适合在开发中使用。举个例子:
我们应该将多线程的使用迁移到 RxJava, 而不是 AsyncTask, 因为 AsyncTask 会导致内存泄漏。
正如我前面所说,AsyncTask 并不会导致内存泄漏。所以上面这句话是错误的。说这句话的开发者并没有深入的研究多线程。此外,他也没有提到 RxJava 的问题。对于一个项目中的开发人员来说,RxJava 存在一个很陡峭的学习曲线。
我们应该为我们的新代码写单元测试,并且设定一个长期的目标,覆盖所有的代码,以确保我们的代码质量。
这句话包含几个前提,首先,我们现在开始单元测试是不可能的,至少需要开发人员投入时间来学习这种技术。编写单元测试是一个很明智的决定。我们不能为所有代码编写单元测试,因为有一些部分是不稳定的。最后,达到特定的覆盖目标并不会自动提高“质量“。在这个例子中,开发者并不了解单元测试,他们无法确定在项目中使用单元测试所涉及的问题和影响。
我希望,你对“技术方案评估”已经有了大致的想法,如果你有一个重要的决定,你需要完成所有必要的调研,如果你依然看不到整个评估中存在的复杂网络,那可能是你的调研没有做好。在做决定的时候,有些事情可能超出技术范围,你也需要考虑你的决策对其它部门同事的影响。
- 专业领域
如何区分一个技术专家和一个普通开发者?是我们熟悉的概念的数量吗?我认为,在技术方面,区分是否是专家主要在于知识上的深度。
作为一个技术专家,你应该有一个或者多个专业领域。你知道这些领域的详细细节,比一般的开发者知道的要多得多。你需要持续深入的研究,来保证你的专业深度,了解专业领域的最新发展,不会对新的工具和技术感到惊讶。此外,即使你并没有在任何项目中使用某些技术,你也需要研究这些技术使用上相关联的各种成本。
现如今,有一个自己的专业领域很难。这不是从博客中挑选几篇好文章进行阅读就可以的,也不是读完几本好书、上完几门好课就可以的。当然,通过这些内容进行学习,对你的专家之路都是有帮助的,但是要有自己的专业领域,唯一的方法就是积极参与其中进行学习研究并获得大量经验。
我很喜欢物理学家尼尔斯·玻尔说的这句话:
An expert is a man who has made all the mistakes which can be made, in a narrow field.(专家就是把领域内所有该犯的错都犯完的人。)
我们可以在哪些领域进行深入研究呢?实际上,几乎所有的都可以进行深入的研究,在软件开发领域,没有任何一个领域会因为太小而不能设置成专业目标。对此,我也有一些建议:
- 架构师筑基语言基础
目前Android APP开发主流语言就是Java语言,Java语言最大的特性就是提高了软件的交互可能性,可以说安卓手机几乎所有应用程序都是利用Java语言来进行编写的。
知识要点:
1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
- 设计思想解读开源框架
随着互联网企业的不断发展,产品项目中的模块越来越多,用户体验要求也越来越高,想实现小步快跑、快速迭代的目的越来越难,插件化技术应用而生。如果没有插件化技术,美团、淘宝这些集成了大量“app”的应用,可能会有几个g那么大。
所以,当今的Android移动开发,不会热修复、插件化、组件化,80%以上的面试都过不了。
知识要点:
1、热修复设计
2、插件化框架设计
3、组件化框架设计
4、图片加载框架
5、网络访问框架设计
6、RXJava响应式编程框架设计
- 360°全方位性能调优
在不同层次的开发工程师手里,因为技术水平的参差不齐,即使很多手机在跑分软件性能非常高,打开应用依然存在卡顿现象。
另外,随着产品内容迭代,功能越来越复杂,UI页面也越来越丰富,也成为流畅运行的一种阻碍。综上所述,对APP进行性能优化已成为开发者该有的一种综合素质,也是开发者能够完成高质量应用程序作品的保证。
知识要点:
1、设计思想与代码质量优化
2、程序性能优化
启动速度与执行效率优化
布局检测与优化
内存优化
耗电优化
网络传输与数据储存优化
APK大小优化
3、开发效率优化
分布式版本控制系统Git
自动化构建系统Gradle
4、项目实战
启动速度
流畅度
抖音在APK包大小资源优化的实践
优酷响应式布局技术全解析
网络优化
手机淘宝双十一性能优化项目揭秘
高德APP全链路源码依赖分析
彻底干掉OOM的实战经验分享
微信Android终端内存优化实践
- Android框架体系架构
Android框架体系架构(高级UI+FrameWork源码) 这块知识是现今使用者最多的,我们称之Android2013~2016年的技术。
Android开发者也往往因为网上Copy代码习惯了而导致对这块经常“使用”的代码熟悉而又陌生:熟悉的是几乎天天在和它们打交道, 天天在复制这些代码 ;陌生的是虽然天天和这些代码打交道,但是并没有深入研究过这些代码的原理,代码深处的内涵。
知识要点:
1、高级UI晋升
2、Android内核组件
3、大型项目必备IPC
4、数据持久与序列化
5、Framework内核解析**
- NDK模块开发(音视频开发系列)
NDK(Native Development Kit缩写)一种基于原生程序接口的软件开发工具包,可以让您在 Android 应用中利用 C 和 C++ 代码的工具。通过此工具开发的程序直接在本地运行,而不是虚拟机。
在Android中,NDK是一系列工具的集合,主要用于扩展Android SDK。NDK提供了一系列的工具可以帮助开发者快速的开发C或C++的动态库,并能自动将so和Java应用一起打包成apk。
知识要点:
1、NDK开发之C/C++入门
2、JNI模块开发
3、Linux编程
4、底层图片处理
5、音视频开发
6、机器学习
- Flutter学习进阶