当前位置:网站首页>Analysis of Mvi Architecture
Analysis of Mvi Architecture
2022-08-05 05:06:00 【slow cavalry】
- This article is simple to useKotlin + 协程 + flow + channelWrite a fake login request案例(dev_20220804_mvi分支),Learn from this caseMvi架构.
- 在了解Mvi之前,建议先了解一下Mvvm,可以参考Mvc、Mvp和Mvvm
一.代码环节
- Just understanding concepts first can feel abstract,We analyze the logic of the code and the class combination corresponding to the codeMviconcept together,会清晰很多;
- The case contains a total of4个类,MainActivity、DemoViewModel、DemoIntent、DemoUiState,先贴上;
1.1.MainActivity
import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
private lateinit var textView: TextView
private val mDemoViewModel: DemoViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
textView = findViewById(R.id.textView)
lifecycleScope.launch {
//3.ViewLayer settings monitor(VMThe layer will actively trigger the callback after executing the corresponding logic according to the intent)
mDemoViewModel.mUiState.collect {
uiState ->
when (uiState) {
is DemoUiState.loginSuccess -> {
textView.setText(uiState.success)
}
is DemoUiState.loginFail -> {
textView.setText("登录失败")
}
is DemoUiState.beforeLogin -> {
textView.setText(uiState.bengin)
}
}
}
}
}
//1.Click the button to simulate a network request
fun login(view: View) {
lifecycleScope.launch {
//1.1.Pass the intent to ViewModel层
mDemoViewModel.mChannel.send(DemoIntent.LoginIntent)
}
}
override fun onDestroy() {
super.onDestroy()
//Channel是一种协程资源['热'流],Communicate across different coroutines
//If you don't close it after use,会造成不必要的浪费
mDemoViewModel.mChannel.close()
}
}
1.2.DemoViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.consumeEach
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
/** * 意图类 * The intent class can be written in the correspondingViewModel类中,No need to go out separately * 好处:Avoid too fine particle size,thereby increasing the complexity of the project */
sealed class DemoIntent {
//The number of intents is added according to actual needs
object LoginIntent : DemoIntent()
}
class DemoViewModel : ViewModel() {
val mChannel = Channel<DemoIntent>()
private val mDemoUiState = MutableStateFlow<DemoUiState>(DemoUiState.beforeLogin("准备登录"))
//使用flow来监听
val mUiState: StateFlow<DemoUiState> = mDemoUiState
init {
handleIntentInfo()
}
private fun handleIntentInfo() {
viewModelScope.launch {
mChannel.consumeEach{
//consumeEach:channel(管道)Read the data recommendation scheme[直接使用receive是很容易出问题的]
//2.Receive the intent transmitted by the user
when(it){
//Why go through an intent here?rather than communication,The purpose is to facilitate management,Views are forV层跟VMLayers are better decoupled and code extensions
is DemoIntent.LoginIntent -> getLoginData()
}
}
}
}
private fun getLoginData() {
viewModelScope.launch {
requestLogin.flowOn(Dispatchers.Default)
.catch {
exception ->
mDemoUiState.value = DemoUiState.loginFail(exception)
}.collect {
loginInfo ->
mDemoUiState.value = DemoUiState.loginSuccess(loginInfo)
}
}
}
private val requestLogin: Flow<String> = flow {
val loginInfo = "登录成功" //Simulate a request to log in to the interface
emit(loginInfo)
}
}
1.3.DemoUiState
sealed class DemoUiState {
//为了降低复杂度,The parameters of the method are written(The parameters inside the brackets in the actual project are recommended to be encapsulated into generics)
data class beforeLogin(var bengin: String):DemoUiState()
data class loginSuccess(var success: String):DemoUiState()
data class loginFail(var exception: Throwable):DemoUiState()
}
- Next, we combine concepts and code to understandMvi
二.Mvi
2.1.站在AndroidThe developer's point of view is simple to understandMvi
- Suppose the user is operating oursApp,To perform a login operation,Then the code level will encapsulate the user's login operation with an intent(对应Mvi的i),Then pass this intent to ViewModel(M层的一部分),然后ViewModelAfter executing the corresponding logic,It will be notified by callbackView层(实现方式有多种,常用的就是Livedata,used in the caseFlow);
- 上面的场景,User action fromV层开始,The final feedback is also thereView层,数据的流向是单向的;
2.2.Mvi和Mvvm的区别
- 多了一个i(corresponding to the caseDemoIntent 类)and one lessdatabinding,Others feel no difference(至于DemoUiState 类,也可以在MvvmThere are also corresponding packages in );
2.3.Compare the code logic
- 从MainActivity的login方法开始,User performs login,Will go through the pipeline of the coroutine(A resource for coroutines,不是本文的重点,了解即可)传递一个DemoIntent.LoginIntent参数,其中DemoIntentA class is an intent class,LoginIntentis a specific intent,As for needDemoIntentHow many intents are defined in the context is determined by specific needs.Wrap the need for login into an intent and pass it to ViewModel层,ViewModel层接收了,对应在DemoViewModel类的handleIntentInfo方法中处理ViewThe intent passed by the layer,We only need to analyze the methodWhen语句即可,判断itWhich one corresponds toDemoIntentThe intent to decide the execution logic,当是DemoIntent.LoginIntentperform login(伪)网络请求()调用到getLoginData方法,Modify after requesting the interfacemDemoUiState.value的值,从而触发MainActivity类中的mDemoViewModel.mUiState设置的监听,然后ViewLayers execute different logic based on different conditions;
三.总结
- This article describes from specific codeMvi不同于Mvvm的点,Mvi的MLayers can correspondMvvm的VM层和M层的结合,Contains both intent and UITwo parts of the state change.The use level is simpler,但是个人觉得Mvi的M层于Mvvmis a bit bloated,And this bloated point everyone can learnMvvmThe advantages ofMviMake flexible changes.
- 关于Mvi的学习,Personally recommend articles-MVVM 进阶版:MVI 架构了解一下~
边栏推荐
- [cesium] 3D Tileset model is loaded and associated with the model tree
- Application status of digital twin technology in power system
- Develop your own node package
- About the installation of sklearn library
- Flex layout frog game clearance strategy
- jvm three heap and stack
- creo怎么测量点到面的距离
- App rapid development and construction experience: the importance of small programs + custom plug-ins
- 社区分享|腾讯海外游戏基于JumpServer构建游戏安全运营能力
- Homework 8.4 Interprocess Communication Pipes and Signals
猜你喜欢
![[cesium] element highlighting](/img/99/504ca9802db83eb33bc6d91b34fa84.png)
[cesium] element highlighting

There are a lot of 4T hard drives remaining, prompting "No space left on device" insufficient disk space

The log causes these pits in the thread block, you have to guard against

Flutter real machine running and simulator running

AUTOCAD——标注关联

8.04 Day35-----MVC三层架构

University Physics---Particle Kinematics

mutillidae download and installation

jvm three heap and stack

浅析主流跨端技术方案
随机推荐
number_gets the specified number of decimals
Use IDEA to connect to TDengine server
小程序_动态设置tabBar主题皮肤
RL强化学习总结(一)
AUTOCAD - dimension association
RL reinforcement learning summary (1)
Excel画图
LAB Semaphore Implementation Details
Flutter learning 2-dart learning
说说数据治理中常见的20个问题
In the hot summer, teach you to use Xiaomi smart home accessories + Raspberry Pi 4 to connect to Apple HomeKit
「PHP8入门指南」PHP简明介绍
为什么刚考完PMP,就开始准备软考了?
MySQL基础(一)---基础认知及操作
write the story about us
【cesium】Load and locate 3D Tileset
Flutter学习4-基本UI组件
MySQL中控制导出文件后变为了\N有什么解决方案吗?
[Nine Lectures on Backpacks - 01 Backpack Problems]
for..in和for..of的区别