Authentication with Architecture Components MVVM, passing token from Repository to ViewModel

xenull :

I want to make an login activity based the "official" MVVM, Repository model.

I have looked at the Android Studio "Login" template and somewhat understood how that works. The flow chart below shows how I plan the data flow between classes. The template did not include the WebService part, instead the token was immediately return without a callback.

Login Flow Chart

Since creating references (in callbacks) to the VM/Activity is bad practice, what are the options for having the token propagated back to the VM (represented by the dashed arrows)?

Notes:

  1. From the VM to Activity, data is passed using LiveData. I understand that step.
  2. I thought about creating LiveData in the Repository, which is then observed in the Activity, skipping the VM. However, surely some logic might need to be done on any data coming from the Repository, so it should first pass through the VM, be processed there and then a derived result observed by the Activity.
  3. It seems difficult to use LiveData to pass data from the Repository to the VM because any call to .observe() in the VM needs a suitable Context. It seems only the Activity can .observe?
  4. To get a better understanding, I would prefer to avoid the use of RxJava and Dagger for now and to work in Java.

Thanks

Vishnu Haridas :

You don't need to create a LiveData inside the repository. Instead, you can make a call from the VM to the repository.login(u,p) and wait for the results to arrive. Once the results has arrived, just update the LiveData instance inside the VM.

The network call must be done asynchronously anyway, or you can make use of the callback mechanism from the networking libraries like Retrofit.

Your ViewModel will look like this (pseudo code):

class LoginViewModel: ViewModel{

    LiveData<Result> login(String username, String password){

        LiveData<Result> resultLiveData = new MutableLiveData<Result>();

        // Let it be an async. call from Retrofit
        Repository.login(username, password, new Callback<Result>{
            void onResult(Result result){
                resultLiveData.value = result  // update the livedata.
            }
        }

        return resultLiveData;

    }

}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=154108&siteId=1