典型的 Android 应用包含多个应用组件,包括Activity、Fragment、Service、ContentProvider和BroadcastReceiver。您需要在manifest中声明其中的大多数应用组件。Android 操作系统随后会使用此文件来决定如何将您的应用集成到设备的整体用户体验中。鉴于典型的 Android 应用可能包含多个组件,并且用户经常会在短时间内与多个应用进行互动,因此应用需要适应不同类型的用户驱动型工作流和任务。
请注意,移动设备的资源也很有限,因此操作系统可能随时终止某些应用进程以便为新的进程腾出空间。
鉴于这种环境条件,您的应用组件可以不按顺序地单独启动,并且操作系统或用户可以随时销毁它们。由于这些事件不受您的控制,因此您不应在内存中存储或保留任何应用数据或状态,并且应用组件不应相互依赖。
常见的架构原则如果您不应使用应用组件存储应用数据和状态,那么您应该改为如何设计应用呢?
随着 Android 应用大小不断增加,您定义的架构务必要能允许应用扩缩、提升应用的稳健性并且方便对应用进行测试。
应用架构定义了应用的各个部分之间的界限以及每个部分应承 ...
模块化是按多个松散耦合的独立部分整理代码库的做法。每个部分都是一个模块。每个模块都是独立的,并且都有明确的用途。通过将问题划分为更小、更易于解决的子问题,您可以降低设计和维护大型系统的复杂性。
高内聚和低耦合原则表征模块化代码库的一种方式是使用耦合和内聚属性。耦合用于衡量模块相互依赖的程度。在本指南中,内聚用于衡量单个模块的不同元素在功能上的相关性。一般而言,您应尽力实现低耦合和高内聚:
低耦合是指模块应尽可能相互独立,这样一来,对一个模块所做的更改将对其他模块产生零影响或极小的影响。模块相互之间不应了解对方的内部运行原理。
高内聚是指多个模块的代码集合应当像一个系统一样运行。它们应具有明确定义的职责,并始终位于特定领域知识范围以内。假设有一个电子书应用示例。在同一个模块中融合图书相关代码和付款相关代码是不合适的,因为图书和付款是两个不同的功能领域。
提示:如果两个模块相互严重依赖对方的信息,则可能表明这两个模块应当作为一个系统运行。相反,如果一个模块的两个部分并不经常相互交互,则这两个部分应当成为两个独立模块。
模块类型您主要依赖于应用架构来组织模块。下面列出了您在遵循我们 ...
离线优先应用是无需访问互联网就能执行全部核心功能或一部分关键核心功能的应用。也就是说,它可以离线执行部分或全部业务逻辑。
构建离线优先应用首先要考虑数据层,它提供对应用数据和业务逻辑的访问。应用可能需要不时刷新这些来自设备外部来源的数据。为此,它可能需要调用网络资源来保持更新。
网络的可用性并不一定总是能得到保证。设备往往免不了会遇到网络连接不稳定或速度缓慢的问题。用户也可能会遇到以下情况:
互联网带宽有限。
连接短暂中断,例如在电梯或隧道中。
偶尔才能访问数据。例如,使用的平板电脑仅支持 Wi-Fi 连接。
不管原因如何,应用通常可以在上述情况下正常运行。为了确保应用可在离线状态下正常运行,它应该具备以下能力:
在没有可靠网络连接的情况下仍可使用。
立即向用户提供本地数据,而不是等待第一次网络调用完成或失败。
提取数据的方式考虑到电池和数据状态。例如,仅在理想情况下(例如充电或有 Wi-Fi 连接时)请求提取数据。
满足上述标准的应用通常称为离线优先应用。
设计离线优先应用在设计离线优先应用时,首先应该设计数据层以及您可以对应用数据执行的以下两项主要操作:
读取:检索数据以 ...
界面层包含与界面相关的状态和界面逻辑,数据层则包含应用数据和业务逻辑。业务逻辑决定应用的价值,它由现实世界的业务规则组成,这些规则决定着应用数据的创建、存储和更改方式。
这种关注点分离使得数据层可用于多个屏幕、在应用的不同部分之间共享信息,以及在界面以外复制业务逻辑以进行单元测试。
架构数据层由多个仓库组成,其中每个仓库都可以包含零到多个数据源。您应该为应用中处理的每种不同类型的数据分别创建一个存储库类。例如,您可以为与电影相关的数据创建一个MoviesRepository类,或者为与付款相关的数据创建一个PaymentsRepository类。
存储库类负责以下任务:
向应用的其余部分公开数据。
集中处理数据变化。
解决多个数据源之间的冲突。
对应用其余部分的数据源进行抽象化处理。
包含业务逻辑。
每个数据源类应仅负责处理一个数据源,数据源可以是文件、网络来源或本地数据库。数据源类是应用与数据操作系统之间的桥梁。
层次结构中的其他层绝不能直接访问数据源;数据层的入口点始终是存储库类。状态容器类或用例类绝不能将数据源作为直接依赖项。如果使用仓库类作为入口点,架构的不同层便可以独立 ...
网域层是位于界面层和数据层之间的可选层。网域层负责封装复杂的业务逻辑,或者由多个ViewModel重复使用的简单业务逻辑。此层是可选的,因为并非所有应用都有这类需求。因此,您应仅在需要时使用该层,例如处理复杂逻辑或支持可重用性。
注意 :“网域层”一词在其他软件架构(例如“干净”架构)中使用,具有不同的含义。请勿将 Android 官方架构指南中定义的“网域层”的定义与您在其他地方看到的其他定义相混淆。二者可能存在细微但很重要的差异。
网域层具有以下优势:
避免代码重复。
改善使用网域层类的类的可读性。
改善应用的可测试性。
让您能够划分好职责,从而避免出现大型类。
为了使这些类保持简单轻量化,每个用例都应仅负责单个功能,且不应包含可变数据。您应在界面或数据层中处理可变的数据。
命名惯例动词原形 + 名词/内容(可选)+ 用例。
例如:LogOutUserUseCase、GetLatestNewsWithAuthorsUseCase。
依赖项在典型的应用架构中,用例类适合界面层的ViewModel与数据层的仓库。这意味着用例类通常依赖于仓库类,并且它们与界面层的通信 ...
界面的作用是在屏幕上显示应用数据,并充当主要的用户互动点。每当数据发生变化时,无论是因为用户互动(例如按了某个按钮),还是因为外部输入(例如网络响应),界面都应随之更新,以反映这些变化。实际上,界面是从数据层获取的应用状态的直观呈现。
不过,从数据层获取的应用数据的格式通常不同于您需要显示的信息的格式。例如,您可能只需要在界面中显示部分数据,或者可能需要合并两个不同的数据源,以便提供切合用户需求的信息。无论您应用的是什么逻辑,都需要向界面传递完全呈现界面所需的所有信息。界面层是一个流水线,负责将应用数据变化转换为界面可以呈现的形式,然后将其显示出来。
注意:本页中提供的建议和最佳实践可广泛应用于许多应用。遵循这些建议和最佳实践可以提升应用的可扩展性、质量和稳健性,并使应用更易于测试。不过,您应该将这些提示视为指南,并视需要进行调整来满足您的要求。
基本案例研究让我们以一个可获取新闻报道供用户阅读的应用为例。该应用有一个报道屏幕,用于显示可供阅读的报道;另外,该应用允许已登录的用户为真正出众的报道添加书签。考虑到随时都可能有大量的报道,读者应能够按类别浏览报道。总的来说,该应用可让 ...
Android
未读Android系统提供了两种显示模式:明亮模式与暗黑模式
亮色模式(Light Model):整体偏亮,即背景亮色,文字等内容暗色
暗黑模式(Dark Model):整体偏暗,即背景暗色,文字等内容亮色。
将decorView的fitSystemWindows属性设置为false
WindowCompat.setDecorFitsSystemWindows(window, false)
设置状态栏颜色为透明
window.statusBarColor = Color.TRANSPARENT
是否需要改变状态栏上的 图标、字体 的颜色
val controller = WindowCompat.getInsetsController(window, window.decorView)
mask:遮罩 默认是false
var mask = true// mask = true 状态栏字体颜色为黑色,一般在状态栏下面的背景色为浅色时使用// mask = false 状态栏字体颜色为白色,一般在状态栏下面的背景色为深色时使用controller.isAppearanceLightSt ...
Homebrew一款Mac OS平台下的软件包管理工具,拥有安装、卸载、更新、查看、搜索等很多实用的功能。简单的一条指令,就可以实现包管理,而不用你关心各种依赖和文件路径的情况,十分方便快捷。
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"brew install google-chrome iina adrive maczip orbstack thunder android-studio visual-studio-code tencent-lemon 4k-video-downloader motrix tinymediamanager
JDKbrew install openjdk@17# 配置环境变量echo 'export PATH=/opt/homebrew/opt/openjdk@17/bin:$PATH' >> ~/.zshrcecho 'export ANDROID_HOME=/U ...