ViewModel+LiveData

前言:对比MVP架构,ViewModel+LiveData实现的MVVM架构代码更加简洁,同时由于ViewModel和Retrofit、Room均可使用Coroutine,简化了获取数据的订阅操作。(ViewModel替代P,LiveData替代V)

实现:

1、ViewModel基类封装

open class BaseViewModel : ViewModel() {
    val isShowLoadingLiveData = MutableLiveData<Boolean>()

    override fun onCleared() {
        super.onCleared()
        viewModelScope.cancel()
    }
}

2、Activity基类

通过抽象createViewModel()方法将创建ViewModel对象交给业务层,方便构造方法传参和activity与fragment共用同一个ViewModel,实现数据共享。

abstract class BaseMvvmActivity<T : BaseViewModel> : BaseActivity() {
    lateinit var mViewModel: T
    private val mLoadingDialog: ProgressDialog by lazy { ProgressDialog(this) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mViewModel = creatViewModel()
        ViewModelProvider(this, ViewModelFactory(mViewModel)).get(mViewModel::class.java)//ViewMode添加生命周期能力
        mViewModel.isShowLoadingLiveData.observe(this, Observer {isShowLoading ->
            if (isShowLoading){
                mLoadingDialog.show()
            }else{
                mLoadingDialog.dismiss()
            }
        })
    }

    /*
      创建ViewMode
    */
    protected abstract fun creatViewModel(): T
}

3、ViewModel工厂类

class ViewModelFactory constructor(private val viewModel: ViewModel): ViewModelProvider.Factory{

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return viewModel as T
    }
}

4、业务层具体ViewModel

fun login(mobile: String, authCode: String){
    isShowLoadingLiveData.value = true
    viewModelScope.launch {
        kotlin.runCatching {
            mUserReapository.loginMvvm(LoginReq(mobile, authCode))
        }.onSuccess {
            isShowLoadingLiveData.value = false
            ARouter.getInstance().build(RouterPath.HualalaApp.PATH_HOME).navigation()
        }.onFailure {
            isShowLoadingLiveData.value = false
        }
    }
}

5、数据层(suspend使用)

interface UserApi {

    @POST("login/rider")
    suspend fun loginMvvm(@Body req: LoginReq): BaseRespone<LoginRes>
}
class UserReapository @Inject constructor() {
    private val mUserApi = RetrofitFactory.instance.create(BaseConstant.SERVICE_HOST).create(UserApi::class.java)

    suspend fun loginMvvm(loginReq: LoginReq): LoginRes{
        return mUserApi.loginMvvm(loginReq).convertMvvm()
    }
}
fun <T> BaseRespone<T>.convertMvvm(): T{
    when(this.code){
        ResultCode.SUCCESS -> return this.data
        ResultCode.ACCESS_TOKEN_EXPIRE -> {
            AppPrefsUtils.remove(AppPrefsUtils.ACCESS_TOKEN)
            AppManager.instance.finishAllActivity()
            ARouter.getInstance().build(RouterPath.HualalaUser.PATH_LOGIN).navigation()
            throw Throwable(this.msg)
        }
        else -> throw Throwable(this.msg)
    }
}

6、登录页面

class LoginActivity : BaseMvvmActivity<LoginViewModel>(){

    override fun creatViewModel(): LoginViewModel {
        return LoginViewModel()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        toHomeTv.setOnClickListener {
            mViewModel.login("18600881234", "123456")
        }
    }
}

7、ViewModel生命周期实现原理

FragmentActivity和Fragment中定义了存放ViewModel集合的ViewModelStore,通过ViewModelProvider将创建的ViewModel添加至ViewModelStore中,然后在FragmentActivity和Fragment生命周期中管理ViewModelStore从而实现生命周期

猜你喜欢

转载自blog.csdn.net/yufumatou/article/details/111184596