实现MVVM LiveData RxJava Dagger数据绑定的正确结构?

问题描述 投票:1回答:1

MainActivity

class MainActivity : AppCompatActivity() {
    @Inject
    lateinit var mainViewModelFactory: mainViewModelFactory
    private lateinit var mainActivityBinding: ActivityMainBinding
    private lateinit var mainViewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mainActivityBinding = DataBindingUtil.setContentView(
                this,
                R.layout.activity_main
        )

        mainActivityBinding.rvmainRepos.adapter = mainAdapter
        AndroidInjection.inject(this)
        mainViewModel =
                ViewModelProviders.of(
                        this@MainActivity,
                        mainViewModelFactory
                )[mainViewModel::class.java]
        mainActivityBinding.viewmodel = mainViewModel
        mainActivityBinding.lifecycleOwner = this
        mainViewModel.mainRepoReponse.observe(this, Observer<Response> {
            repoList.clear()
            it.success?.let { response ->
                if (!response.isEmpty()) {
                    //     mainViewModel.saveDataToDb(response)
                    //     mainViewModel.createWorkerForClearingDb()
                }
            }
        })
    }
}

MainViewModelFactory

class MainViewModelFactory @Inject constructor(
        val mainRepository: mainRepository
) : ViewModelProvider.NewInstanceFactory() {

    override fun <T : ViewModel?> create(modelClass: Class<T>) =
            with(modelClass) {
                when {
                    isAssignableFrom(mainViewModel::class.java) -> mainViewModel(
                            mainRepository = mainRepository
                    )
                    else -> throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
                }
            } as T
}

MainViewModel

class MainViewModel(
        val mainRepository: mainRepository
) : ViewModel() {

    private val compositeDisposable = CompositeDisposable()
    val mainRepoReponse = MutableLiveData<Response>()
    val loadingProgress: MutableLiveData<Boolean> = MutableLiveData()
    val _loadingProgress: LiveData<Boolean> = loadingProgress
    val loadingFailed: MutableLiveData<Boolean> = MutableLiveData()
    val _loadingFailed: LiveData<Boolean> = loadingFailed
    var isConnected: Boolean = false

    fun fetchmainRepos() {
        if (isConnected) {
            loadingProgress.value = true
            compositeDisposable.add(
                    mainRepository.getmainRepos().subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe({ response ->
                                run {
                                    saveDataToDb(response)
                                    )
                                }
                            },
                                    { error ->
                                        processResponse(Response(AppConstants.Status.SUCCESS, null, error))
                                    }
                            )
            )
        } else {
            fetchFromLocal()
        }
    }

    private fun saveDataToDb(response: List<mainRepo>) {
        mainRepository.insertmainUsers(response)
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .subscribe(object : DisposableCompletableObserver() {
                    override fun onComplete() {
                        Log.d("Status", "Save Success")
                    }

                    override fun onError(e: Throwable) {
                        Log.d("Status", "error ${e.localizedMessage}")
                    }
                })
    }
}

MainRepository

interface MainRepository {

    fun getmainRepos(): Single<List<mainRepo>>

    fun getAllLocalRecords(): Single<List<mainRepo>>

    fun insertmainUsers(repoList: List<mainRepo>): Completable
}

MainRepositoryImpl

class mainRepositoryImpl @Inject constructor(
        val apiService: GitHubApi,
        val mainDao: AppDao
) : MainRepository {

    override fun getAllLocalRecords(): Single<List<mainRepo>> = mainDao.getAllRepos()

    override fun insertmainUsers(repoList: List<mainRepo>) :Completable{
        return   mainDao.insertAllRepos(repoList)
    }

    override fun getmainRepos(): Single<List<mainRepo>> {
        return apiService.getmainGits()
    }
}

我对用LiveData和Rxjava实现MVVM感到很困惑,在MainViewModel中,我调用接口方法并在ViewModel中实现它,并且在响应中,我也将响应保存到db。但是,这是一个私有方法,无法以适当的方式在单元测试中进行测试(因为它是私有的)。在一个方法完成时调用其他方法的最佳实践是什么,或者我必须在使用该接口的实现类中实现所有方法。

android data-binding rx-java2 android-livedata dagger
1个回答
0
投票

如果您尝试遵循简洁的架构模式,您的ViewModel应该不在乎如何获取数据。从本地或远程源获取数据的逻辑应该在最坏的情况下存储在存储库中,在此情况下您还可以保存响应。在这种情况下,由于您已经联系了这些方法,因此可以轻松对其进行测试。理想情况下,您可以进一步分解-添加用例/交互器。

© www.soinside.com 2019 - 2024. All rights reserved.