MVVM architecture in android Using Volley

EndiveDeCyrodiil :

I'm studying the MVVM to see if it can help me for my upcoming projects. What I understand so far, is that I need to use a ViewModel for holding my UI datas. I also need to use a Repository class to perform all my Requests to WebServices, and I'm using the Volley Library.

So here's what I did :

The ViewModel

public class MyViewModel extends ViewModel {

    private MyRepository repository;
    private MutableLiveData<MyPojo> pojo;

    public MyViewModel(MyRepository repository) {
        this.repository = repository;
        this.pojo = new MutableLiveData<>();
    }

    public LiveData<MyPojo> updatePojo(){
        pojo.postValue(repository.getPojo());
        return pojo;
    }
}

The Repository class

public class MyRepository {

private Application application;
private LiveData<MyPojo> pojo;

public MyRepository(Application application) {
    this.application = application;
}

public MyPojo getPojo(){
    if(pojo == null){
        ApiRequest apiRequest = new ApiRequest(ApiSingleton.getInstance(application).getRequestQueue(), application);
        apiRequest.apiGetRequest(ApiRequest.MY_ENDPOINT, null, new ApiRequest.apiCallback() {
            @Override
            public void onSuccess(Context context, JSONObject jsonObject) {
                pojo = ApiResponseParser.parse(jsonObject, MyPojo.class);
            }

            @Override
            public void onError(Context context, String message) {

            }
        });
    }
    return pojo;
}

}

It's specified here that a ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context. As you can see, I must use a context in order to perform a Volley request in my Repository class, and my ViewModel has a reference on this class.

Am I missing something in my design? Is Volley not compatible here?

Bob :

Instead of passing the Application to your MyRepository's constructor and creating ApiRequest, you can pass the ApiRequest to MyRepository's constructor.

public MyRepository(ApiRequest apiRequest) {
    this.apiRequest = apiRequest;
}

Now the MyRepository has no reference to Context.

And, regarding ViewModel having direct reference to MyRepository, you can do dependency inversion:

Create an interface, for instance, MyDataStore with the method getPojo(). MyRepository will implement this interface. While creating MyViewModel, you will pass the MyRepository to it, but MyViewModel will only have reference to MyDataStore.

interface MyDataStore {
   ... getPojo()
}

public class MyRepository implements MyDataStore {
   ...
}

public MyViewModel(MyDataStore dataStore) {
        this.dataStore = dataStore;
        this.pojo = new MutableLiveData<>();
}

Guess you like

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