本页介绍了一些与架构有关的最佳实践和建议。采用这些最佳实践和建议不仅可以提高应用的质量、稳健性和可伸缩性,还可以让您的应用更便于维护和测试。
界面层
界面层的作用是在屏幕上显示应用数据,并充当主要的用户互动点。以下是一些有关界面层的最佳实践:
- 您应该创建代码库,即使它们只包含一个数据源也不例外。
- 在小型应用中,您可以选择将数据层类型放置在
data软件包或模块中。
建议 |
说明 |
遵循单向数据流 (UDF) 原则。 强烈建议 |
遵循单向数据流 (UDF) 原则,即 ViewModel 使用观察者模式来公开界面状态,并通过方法调用接收来自界面的操作。 |
如果 AAC ViewModel 的优势适用于您的应用,请加以使用。 强烈建议 |
使用 AAC ViewModel 处理业务逻辑,并提取应用数据以向界面公开界面状态。 |
使用生命周期感知型界面状态收集方式。 强烈建议 |
使用适当的生命周期感知型协程构建器 详细了解 |
请勿将来自 ViewModel 的事件发送到界面。 强烈建议 |
在 ViewModel 中立即处理事件,并通过事件的处理结果引发状态更新。如需详细了解界面事件,请访问此处。 |
使用单 activity 应用。 推荐 |
如果您的应用包含多个屏幕,请使用 Navigation Fragments 在屏幕之间导航以及深层链接到您的应用。 |
以下代码段简要说明了如何以生命周期感知型方式收集界面状态:
class MyFragment : Fragment() {
private val viewModel: MyViewModel by viewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect {
// Process item
}
}
}
}
}
ViewModel
ViewModel 负责提供界面状态和对数据层的访问权限。以下是一些有关 ViewModel 的最佳实践:
建议 |
说明 |
ViewModel 应该与 Android 生命周期无关。 强烈建议 |
ViewModel 不应存储对任何与生命周期相关的类型的引用。请勿将 |
使用协程和数据流。 强烈建议 |
ViewModel 通过以下方式与数据层或网域层交互:
|
在屏幕级别使用 ViewModel。 强烈建议 |
请勿在可重复使用的界面部分中使用 ViewModel。您应该在以下位置使用 ViewModel:
|
请勿使用 强烈建议 |
使用 |
公开界面状态。 推荐 |
ViewModel 应该通过名为
|
以下代码段简要说明了如何从 ViewModel 公开界面状态:
@HiltViewModel
class BookmarksViewModel @Inject constructor(
newsRepository: NewsRepository
) : ViewModel() {
val feedState: StateFlow<NewsFeedUiState> =
newsRepository
.getNewsResourcesStream()
.mapToFeedState(savedNewsResourcesState)
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = NewsFeedUiState.Loading
)
// ...
}
生命周期
以下是一些有关如何使用 Android 生命周期的最佳实践:
建议 |
说明 |
请勿替换 activity 或 fragment 中的生命周期方法。 强烈建议 |
请勿替换 activity 或 fragment 中的 |
以下代码段简要说明了如何在特定生命周期状态下执行操作:
class MyFragment: Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
// ...
}
override fun onPause(owner: LifecycleOwner) {
// ...
}
}
}
}