-3

I am currently self learning on implementing the MVVM architecture in Android. I'm completely new so please help me out. I'll explain the app that I'm working on first.

I would like to make an app that polls a remote server every N seconds and display the updated data in the UI. In the UI, the user should be able to delete and edit data as well (from the existing list of data, no updating the server).

At the moment I have packages and classes for the Model, Repository, ViewModel and View layers. Repository class returns data in MutableLiveData type, ViewModel calls Repository class and returns the data in LiveData type and View observes the LiveData by calling the ViewModel class.

Currently, I am receiving the Network on Main Exception which from what I understand, I have to create an AsyncTask to handle this. However, it's depreciated so I would like to use other options like Executor.

A Java suggestion would be better preferred. Which layer should Executor class should be in? Furthermore, how can I poll the server every N seconds? Which class should be responsible for polling and in which layer?

llamaro25
  • 642
  • 1
  • 7
  • 22

1 Answers1

2

So first of all, as you already read, do not use AsyncTask as it is deprecated, but you are on a good way already.

Have you heard about coroutines (see link #1 and #2)? They are light-weight threads which are made for asynchronous, non-blocking code and perfect for your needs. You easily start one in your viewModel (with e.g. "viewModelScope", see #3), call your method from your repository (or usecase if you have them, but not necessary) to fetch data from the network (retrofit or whatever you use) and mark the functions as suspend functions (suspend function is a function that can be paused and continued later -> when network call is done). In the viewModel you get the data and can easily switch data (see #4) from mutableLiveData to liveData and observe the liveData from your view.

Short Example:

Fragment:

viewModel.data.observe(viewLifecycleOwner, Observer {
    // connect data to your recyclerView adapter
})

ViewModel:

private val _data = MutabeLiveData<Model>()
val data: LiveData<Model> = _data


fun getData() {
   viewModelScope.launch {
        // call your repo / usecase to get data
        val data = repository.getData()
        _data.postValue(data)
   }
}

Repository:

suspend fun getData(): Data {
    // call your network client to get the data you want
    return api.getData()
}

Note: I would suggest you to use interfaces for the api and repository and inject them (repository interface in viewModel, api interface in repository ..) but this is out of scope and only if you know about dependency injection ;-)

Have a look at those resources:

  1. https://developer.android.com/kotlin/coroutines
  2. https://kotlinlang.org/docs/reference/coroutines-overview.html
  3. https://medium.com/androiddevelopers/easy-coroutines-in-android-viewmodelscope-25bffb605471
  4. https://medium.com/androiddevelopers/livedata-beyond-the-viewmodel-reactive-patterns-using-transformations-and-mediatorlivedata-fda520ba00b7
thehrlein
  • 133
  • 1
  • 4
  • thanks for the resources! what if I'm coding in java? coroutines seem like a Kotlin exclusive feature :/ – llamaro25 Apr 30 '20 at 08:00
  • sorry, did not know that you code in java. But for java i'd recommend to have a look at RxJava2, where you can switch between main thread and e.g. IO-Thread easily. Have a look at this (skip the dagger part): https://android.jlelse.eu/android-mvvm-with-dagger-2-retrofit-rxjava-architecture-components-6f5da1a75135. The interesting part is: ".subscribeOn(Schedulers.io() .observeOn(AndroidSchedulers.mainThread())". Subscribe on IO thread but observe on main (UI) thread. There are plenty of examples and tutorials to help you, try to search for e.g. rxjava2 and viewmodel :) – thehrlein May 02 '20 at 12:30