2023 版现代 Android 开发概览

323 阅读19分钟

作者:bytebeats
juejin.cn/post/7229151797415051322

什么是 Android?

Android 是一种基于 Linux 内核并由 Google 开发的开源操作系统。它用于各种设备,包括智能手机、平板电脑、电视和智能手表。

目前,Android 是世界上移动设备使用最多的操作系统;根据statcounter的一份最近 12 个月的样本报告,Android 的市场份额为71.96%。

接下来,我将提及我认为对于在 Android 上构建现代应用程序很重要的工具、库、体系结构、指南和其他实用程序的列表。

Kotlin

kotlinlang.org/docs/home.h…

图片

Kotlin 是由JetBrains开发的一种编程语言。由谷歌推荐,谷歌于 2017 年 5 月正式宣布Kotlin作为Android开发语言。它是一种与 Java 兼容并可以运行在 JVM 上的现代编程语言,这使得它在 Android 应用程序开发中的采用速度非常快。

不管你是不是Android新手,你都应该把Kotlin作为你的首选,不要逆水行舟,Google在Google I/O 2019上宣布了这种做法。有了Kotlin,你将可以使用所有现代语言的特性,包括协程的强大功能和使用为 Android 生态系统开发的现代库。

Jetpack Compose

developer.android.com/jetpack/com…

图片

Jetpack Compose是Android推荐的用于构建本地UI的现代工具包.它简化并加速了Android上的UI开发。

Jetpack Compose是Android Jetpack库的一部分, 使用Kotlin编程语言来轻松创建本地用户界面.同时, 它还与其他Android Jetpack库(如LiveData和ViewModel)集成, 使其更容易建立反应性和可维护的Android应用程序. Jetpack Compose的一些主要特点包括:

  • 声明式UI.
  • 可定制的小工具.
  • 易于与现有代码集成.
  • 实时预览.
  • 改进性能.

目前 GooglePlay Top1000 的应用中使用 Compose 的已经超过了 25%,其中不乏一些领域头部应用,Compose 的稳定性和成熟度也借机得到了验证。

图片

Android Jetpack

developer.android.com/jetpack

图片

Jetpack 是一套库,可帮助开发人员遵循最佳实践、减少样板代码并编写可跨 Android 版本和设备一致工作的代码,以便开发人员可以专注于他们关心的代码。

常用工具集链接
ViewModeldeveloper.android.com/topic/libra…
Roomdeveloper.android.com/training/da…
DataSourcedeveloper.android.com/topic/libra…
WorkManagerdeveloper.android.com/topic/libra…
Navigationdeveloper.android.com/guide/navig…
Cameradeveloper.android.com/training/ca…
Composedevjorgecastro.medium.com/modern-andr…

Material Design

m3.material.io/

图片

Material Design 是一个适应性强的指南、组件和工具系统,支持用户界面设计的最佳实践。在开源代码的支持下,Material Design 简化了设计人员和开发人员之间的协作,并帮助团队快速构建精美的产品。

Material Design 得到了 Google 的设计师和开发人员的支持,这将使我们有一个指南来处理 Android、Flutter 和 Web 的 UI/UX。

目前, Material Design的最后一个版本是 Material 3。而且 Material 3 对 Compose 也有很好的支持

图片

整洁架构

blog.cleancoder.com/uncle-bob/2…

图片

Clean Architecture的概念是由Robert C. Martin提出的.它的基础是通过将软件划分为不同的层来分离责任。

它有以下一些特点:

  • 独立于框架.
  • 可测试.
  • 独立于用户界面.
  • 独立于数据库.
  • 独立于任何外部代理.
  • 依赖性规则

其中,依赖性规则使该体系结构起作用的最重要规则是依赖规则。这条规则说源代码依赖只能指向内部。内圈中的任何人都无法对外圈中的事物一无所知。特别是,在外圈中声明的名称不得在内圈中的代码中提及。这包括函数、类。变量,或任何其他命名的软件实体。

安卓系统中的Clean Architecture

  • 表示层: Activities, Fragments, ViewModels, 其他视图组件.
  • 领域层: 用例, 实体, 仓库, 其他的域组件.
  • 数据层: 存储库的实现, 映射器, DTO等.

表现层架构

developer.android.com/topic/archi…

架构模式是一种更高级别的策略,旨在帮助设计软件架构,其特点是在可重用框架内为常见架构问题提供解决方案。
架构模式类似于设计模式,但它们的规模更大,并且解决更多的全局问题,例如系统的整体结构、组件之间的关系以及数据的管理方式。在表现层架构中, 我们讨论比较多的是以下两种模式:

  • MVVM:在MVVM设计模式中,视图层与逻辑层进行单向通信,逻辑层与数据层进行双向通信。当用户对视图进行操作时,视图会将事件传递给逻辑层;逻辑层根据事件类型调用相应的业务逻辑,并更新数据;数据变化后会自动同步到逻辑层;逻辑层再根据数据变化自动更新视图。

  • MVI:MVI是Model-View-Intent的缩写,是一种最新的安卓应用开发架构模式,受到了Cycle.js框架中单向数据流和循环性质的启发。MVI与其它常见的架构模式,如MVC、MVP或MVVM,有着很大的不同。

图片

依赖注入

依赖注入是一种软件设计模式,它允许客户端从外部源获取其依赖项,而不是自己创建它们。它是一种用于在对象及其依赖项之间实现控制反转 (IoC) 的技术。

常用库链接
Hiltdeveloper.android.com/training/de…
Daggerdagger.dev/
Koininsert-koin.io/

Hilt Dagger 和 Koin 都是在 Android 开发中常用的依赖注入框架,它们各自有一些特点和适用场景。Hilt Dagger:Hilt Dagger 是由 Google 推出的依赖注入框架,是 Dagger 2 的扩展库。以下是 Hilt Dagger 的一些特点:

  • 官方支持:Hilt 是由 Google 官方推荐和支持的依赖注入框架,因此在技术支持和文档方面能够得到广泛的支持和资源。

  • 简化配置:Hilt 提供了一组注解,简化了 Dagger 的配置过程。通过使用这些注解,开发者可以更轻松地进行依赖注入的设置,减少了样板代码的编写。

  • 自动生成代码:Hilt 使用注解处理器生成用于依赖注入的代码。这意味着开发者无需手动编写大量的依赖注入代码,而是通过声明注解来指示 Hilt 自动生成所需的代码。

  • Android 平台集成:Hilt 针对 Android 平台进行了优化,并提供了与 Android 架构组件(如 ViewModel、Activity、Fragment 等)的无缝集成。它能够自动管理和注入这些组件的依赖关系。

  • 支持多模块项目:Hilt 提供了对多模块项目的支持,可以在不同的模块中使用 Hilt 进行依赖注入,并实现模块之间的解耦。

Koin:Koin 是一个轻量级的依赖注入框架,专为 Kotlin 开发者设计。以下是 Koin 的一些特点:

  • 轻量级:Koin 是一个非常轻量级的依赖注入框架,不依赖于代码生成或反射,因此对应用程序的构建时间没有显著影响。它使用简单的 DSL(领域特定语言)来配置依赖关系。

  • Kotlin 优化:Koin 是专为 Kotlin 语言设计的,利用了 Kotlin 的语言特性和扩展函数。这使得在 Kotlin 代码中使用 Koin 更加流畅和直观。

  • 配置简单:Koin 的配置过程非常简单,通过模块和定义注入的方式来组织和配置依赖关系。开发者只需声明依赖关系,然后可以在需要时进行注入。

  • 无侵入性:Koin 不需要改变现有的类或代码结构,因此可以轻松地将其集成到现有项目中。这使得在现有代码库中使用 Koin 变得非常方便。

  • 容易学习:Koin 的 API 设计简单明了,易于学习和理解。它提供了一个直观的方式来定义和注入依赖关系,使得开发者能够快速上手。

总结来说,Hilt Dagger 是一个官方推荐和支持的依赖注入框架,适用于需要与 Android 架构组件紧密集成的项目。而 Koin 是一个轻量级的依赖注入框架,适用于对简单性和快速上手有较高要求的项目。

根据项目的需求、团队的技术背景和个人偏好,开发者可以选择适合自己的依赖注入框架。

模块化工程架构

developer.android.com/topic/modul…

图片

架构模式是一种更高级别的策略,旨在帮助设计软件架构,其特点是在可重用框架内为常见架构问题提供解决方案。架构模式类似于设计模式,但它们的规模更大,并且解决更多的全局问题,例如系统的整体结构、组件之间的关系以及数据的管理方式。

模块化的好处:

图片

网络

这个大家都很熟悉了,不赘述了。

常用库链接
Okhttpsquare.github.io/okhttp/
Retrofitsquare.github.io/retrofit/

序列化

在本节中,我想提一下我认为的两个重要工具:Moshi与 Retrofit 和Kotlin Serialization一起广泛使用,这是 Jetbrain 的 Kotlin 团队的赌注。

常用库链接
Moshigithub.com/square/mosh…
Kotlin Serializationgithub.com/Kotlin/kotl…

Moshi和Kotlin Serialization是 Kotlin 和 Java 的两个序列化/反序列化库,允许您将对象转换为 JSON 或其他序列化格式,反之亦然。

两者都提供了针对移动和桌面应用程序优化的用户友好界面。Moshi 主要关注 JSON 序列化,而 Kotlin 序列化支持各种序列化格式,包括 JSON。

图片加载

developer.android.com/jetpack/com…

要从 Internet 加载图像,可以使用多个第三方库来帮助您处理该过程。图像加载库为您做了很多繁重的工作;它们处理缓存(因此您不会多次下载图像)和网络逻辑以下载图像并将其显示在屏幕上。

常用库链接
Coilgithub.com/coil-kt/coi…
Glidebumptech.github.io/glide/int/c…

线程管理

图片

当我们谈论反应式编程和异步过程时,我们的第一个选择是Kotlin Coroutines;多亏了Suspension Functions,Flow我们可以满足所有这些需求。但是,我相信在本节中值得强调RxJava甚至在 Android 应用程序开发中的重要性。对于我们这些已经使用 Android 多年的人来说,我们知道 RxJava 是一个非常强大的工具,具有大量用于处理数据流的功能。我仍然认为 RxJava 是今天值得考虑的一个有趣的替代方案。

常用库链接
Kotlin协程github.com/Kotlin/kotl…
RxJavagithub.com/ReactiveX/R…

本地存储

本地存储构建移动应用程序的一个重点是能够在本地持久保存数据,例如一些会话数据或缓存数据等。根据您的应用需求选择正确的存储选项非常重要。我们可以存储键值对等非结构化数据或数据库等结构化数据。请记住,这一点并未提及我们可用的所有类型的本地存储(例如文件存储),仅提及允许我们保存数据的工具。

图片

常用库链接
S̶h̶a̶r̶e̶d̶P̶r̶e̶f̶e̶r̶e̶n̶c̶e̶s̶
DataStoredeveloper.android.com/topic/libra…
EncryptedSharedPreferencesdeveloper.android.com/reference/a…

测试

常用库链接
JUnit 5junit.org/junit5/
Mockkmockk.io/ANDROID.htm…
Espressodeveloper.android.com/training/te…
Robolectricrobolectric.org/

R8优化

R8 是默认编译器,可将项目的 Java 字节码转换为可在 Android 平台上运行的 DEX 格式。它是一种工具,通过缩短类及其属性的名称,消除项目中未使用的代码和资源,帮助我们混淆和减少应用程序的代码。要了解更多信息,请查看有关收缩、混淆和优化您的应用程序的Android 文档。

  • 代码缩减

  • 资源缩减

  • 混淆

  • 优化

混淆是 R8 在 D8 基础上增加的最为重要的能力,通过开启Shrinking,可以对源码进行优化,以达到减小包体积的目的,具体包括但不限于:

  • 代码删除:通过语法树静态分析技术,发现并剔除未使用的代码,例如没有被实例化的Class等
  • 代码优化:对运行时代码进行优化,包括死代码删除、未使用的参数删除、选择性内联、类合并等。
  • 代码混淆:优化标识符名字,减少代码数量,例如MyAwesomeClass可能被优化成单一字母a

Play特性交付

developer.android.com/guide/playc…

图片

Google Play 的应用服务模型称为 Dynamic Delivery,它使用 Android App Bundle 为每个用户的设备配置生成和提供优化的 APK,因此用户仅下载运行您的应用所需的代码和资源。

自适应布局

随着具有不同形状因素的移动设备使用的增长,我们需要有工具使我们能够使用适应不同类型屏幕的 Android 应用程序。这就是 Android 为我们提供Window Size Classes的原因,简单来说,它是三大屏幕格式组,它们标记了我们开发设计的关键点。有了这个,我们避免了考虑许多屏幕设计的复杂性,将我们的可能性减少到 3 组,即:Compat、Medium和Expanded 。 

为应对更多种类屏幕的出现,Jetpack 提供了 WindowManager 库,便于 App 更好地适配不同屏幕的尺寸。多窗口模式下的 App 不能再依赖 Display.getRealMetrics() 获取窗口尺寸,当屏幕状态变化导致,OnConfigurationChanged 发生时,使用 WindowManager 的 WindowMetrics 获取准确的窗口尺寸,再根据 WindowSizeClass 以最合适的布局显示当前 UI。

图片

图片

一些相关资源链接
3 things to know about Form Factors at Google I/O 20223 things to know about Form Factors at Google I/O 2022
Playlist: Form Factors at Google I/Owww.youtube.com/playlist?li…
Form-Factor Trainingdeveloper.android.com/courses/pat…
Form Factors at Google I/O 2022 (2)www.youtube.com/playlist?li…

性能

当我们为 Android 开发应用程序时,我们必须确保更好的用户体验,不仅在应用程序开始时,而且在整个执行过程中。出于这个原因,拥有使我们能够对可能影响应用程序性能的情况进行预防性分析和持续监控的工具非常重要

图片

相关工具链接
Benchmarkdeveloper.android.com/topic/perfo…
Baseline Profiledeveloper.android.com/topic/perfo…
App Startupdeveloper.android.com/topic/libra…
Firebase Performancefirebase.google.com/docs/perf-m…
JankStatsdeveloper.android.com/topic/perfo…

其中,Baseline Profile 是今年 Android 在性能方面发布的重磅功能。
Android 8.0 之后默认开启 ART 虚拟机。ART 最初版本在安装应用时会对全部代码进行 AOT 预编译,将字节码转换为机器码存在本地,这提升了运行时的速度,但是会导致安装过程变慢。因此后来 ART 改进为 JIT 和 AOT 相结合的方式,在应用安装时只将热点代码编译成机器码,缩短安装时间。

图片

Baselin Profiles 基准配置文件允许我们配置哪些代码成为热点代码。基准配置文件将在 APK 的 assets/dexopt/baseline.prof 中编译为二进制形式,例如如果我们想提升首帧的性能,可以将应用启动或帧渲染期间使用的方法配置到 prof 文件中。

应用内更新

developer.android.com/guide/playc…

图片

当您的用户让您的应用程序在他们的设备上保持最新时,他们可以尝试新功能,并从性能改进和错误修复中受益。尽管某些用户在其设备连接到不按流量计费的连接时启用后台更新,但可能需要提醒其他用户安装更新。应用内更新是一项 Google Play 核心库功能,可提示活跃用户更新您的应用。

运行 Android 5.0(API 级别 21)或更高版本的设备支持应用内更新功能。此外,仅 Android 移动设备、Android 平板电脑和 Chrome 操作系统设备支持应用内更新。

应用内评论

developer.android.com/guide/playc…

图片

Google Play 应用内评论 API 可让您提示用户提交 Play 商店评分和评论,而无需离开您的应用或游戏。

通常,应用内评论流程可以在应用的整个用户旅程中随时触发。在此流程中,用户可以使用 1 到 5 星系统对您的应用进行评分并添加可选评论。提交后,评论将发送到 Play 商店并最终显示。

为保护用户隐私并避免 API 滥用,您的应用应遵循有关何时请求应用内评论和评论提示设计的严格指南。

无障碍辅助功能

图片

辅助功能是软件设计和构造中的一个重要功能,除了改善用户体验外,它还为需要辅助功能的人提供使用应用程序的能力。该概念旨在改善的一些残障人士包括:有视力问题、色盲、听力问题、灵活性问题和认知障碍等的人。

考虑的因素:

  • 增加文本的可见性(颜色对比, 可调整文本).
  • 使用大型,  简单的控件
  • 描述每个用户界面元素

辅助功能官方文档 developer.android.com/guide/topic…

版本目录

docs.gradle.org/current/use…

Gradle提供了一种集中管理项目依赖关系的标准方式, 称为版本目录(Version Catalog);它在7.0版本中试验性地引入, 并在7.4版本中正式发布。其优点是:

  • • 对于每个目录,Gradle 都会生成类型安全的访问器,以便您可以在 IDE 中轻松添加具有自动完成功能的依赖项。
  • • 每个目录对构建的所有项目都是可见的。它是声明依赖项版本并确保对该版本的更改适用于每个子项目的中心位置。
  • • 目录可以声明依赖包,它们是通常一起使用的“依赖组”。
  • • 目录可以将依赖项的组和名称与其实际版本分开,并使用版本引用代替,从而可以在多个依赖项之间共享版本声明。

安全性

图片

安全性即使不是最重要的方面,也是我们在开发保护设备完整性、数据安全性和用户信任的应用程序时必须考虑的因素,这就是为什么我在下面列出一系列帮助您实现此目的的提示。

图片

Linter

图片

Android Lint 是一个静态代码分析工具,用于帮助开发者发现和修复 Android 应用中的潜在问题和错误。Lint 在构建过程中会对代码进行扫描,并提供有关代码质量、性能、安全性和可维护性方面的建议。

以下是 Android Lint 的一些重要特点和功能:

  1. 代码规范检查:Lint 可以检查代码是否符合 Android 的最佳实践和规范。它会发现不符合命名约定、错误的资源引用、不必要的代码、未使用的资源等问题,并提供相应的建议和修复方法。
  2. 潜在错误检测:Lint 可以发现潜在的错误和问题,例如空指针引用、资源泄漏、未处理的异常、可能引发崩溃的代码等。通过这些检查,开发者可以避免一些常见的错误和异常情况。
  3. 性能分析:Lint 可以帮助开发者发现性能方面的问题。例如,它可以检查是否存在过度绘制、不必要的布局层次、内存泄漏等。这有助于优化应用的性能和响应性。
  4. 安全性检查:Lint 可以扫描代码中的安全漏洞和潜在的安全隐患。例如,它可以检查敏感数据的处理方式、未加密的网络请求、未授权的访问等。这有助于提高应用的安全性。
  5. 自定义规则:除了默认提供的规则之外,Lint 还支持自定义规则。开发者可以根据自己的需求编写自定义规则,以检查和强制执行特定的代码规范和最佳实践。

通过集成 Lint 到 Android 项目中,开发者可以在开发过程中自动进行代码检查,并及时发现和修复问题。Lint 可以与 Android Studio 和 Gradle 构建系统无缝集成,使得开发者能够快速获得代码质量和性能方面的反馈。

常用库链接
Android Lintmedium.com/swlh/what-i…
Detektdetekt.dev/
Ktlintpinterest.github.io/ktlint/

Logger

logger是一种软件工具,用于记录有关程序执行的信息;重要事件、错误、调试消息和其他可能有助于诊断问题或了解程序工作方式的信息。记录器可以配置为将消息写入不同的位置,例如日志文件、控制台、数据库,或者通过将消息发送到日志服务器。

常用库链接
Timbergithub.com/JakeWharton…

除了常用的 LogCat,Timber 也是一个非常不多的选择,Timber 是一个 Android 平台上流行的日志库,它提供了简单而强大的日志记录功能,帮助开发者在应用程序中更好地管理和输出日志信息。以下是 Timber 日志库的一些重要特点和功能:

  • 简单易用:Timber 提供了简洁的 API,使得在应用中使用日志变得非常方便。它使用了一种类似于 Android 的 Logcat 的接口,开发者可以直接调用 Timber.d()、Timber.i()、Timber.w()、Timber.e() 等方法来输出不同级别的日志信息。
  • 可扩展性:Timber 具有高度可扩展性,可以根据开发者的需求进行自定义配置。它允许开发者实现自定义的 Tree 类,以将日志信息输出到不同的目标,如 Logcat、文件、Crashlytics 等。这样,开发者可以根据实际需求灵活地定制日志记录行为。
  • 上下文感知:Timber 可以自动获取日志输出的上下文信息,如类名、方法名和行数等。这样,开发者无需手动编写这些信息,能够更轻松地定位日志输出的位置,方便调试和排查问题。
  • 调试模式支持:Timber 提供了调试模式的支持,可以在开发环境中输出详细的日志信息,而在发布版本中禁用日志输出或只输出关键信息。这有助于保护敏感信息并减少应用程序的日志记录量。
  • 线程安全:Timber 在处理日志输出时是线程安全的,可以在多线程环境中使用而不用担心竞争条件或线程安全问题。