Search code examples
androidretrofit2viewmodel

One method get respond from WebServer and other method need answer of that method to return something , and unfortunately I got null


In MainActivityViewModel class i have one Getter method that returns an instance of CurrentWeather (pojo class) and this method needs response from OnResponse method but I get null for first time.

The first methods invoke from MainActivity, viewModel is not null but the currentWeather instance is.

MainActivityViewModel viewModel = ViewModelProviders.of(this).get(MainActivityViewModel.class);
currentWeather = viewModel.getCurrentWeather();

I don't know if I can ask to wait for a moment before return currentWeather in first method or not.

public class MainActivityViewModel extends ViewModel implements Callback<ResponseBody> {

    private CurrentWeather currentWeather;

    public CurrentWeather getCurrentWeather() {
        if (currentWeather == null) {
            createCurrentWeather("London");
        }
        return currentWeather;
    }

    public void createCurrentWeather(String city) {
        RetrofitApiManager.getInstance().getCurrentWeatherApi(this, city);
    }

    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {

        if (response.isSuccessful()) {
            ResponseBody body = response.body();
            try {
                String serverResponde = body.string();
                Timber.e(serverResponde);
                Gson gson = new Gson();
                currentWeather = gson.fromJson(serverResponde, CurrentWeather.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
    }
}

Solution

  • It's because it takes a while before a response is returned.

    Usually, you need a LiveData object to get results from background tasks.

    In your MainActivityViewModel, add the following:

    private MutableLiveData currentWeatherData = new MutableLiveData<CurrentWeather>();
    
    public LiveData<CurrentWeather> getCurrentWeatherData() {
        return currentWeatherData;
    }
    

    When you get response, update your LiveData

    currentWeather = gson.fromJson(serverResponde, CurrentWeather.class);
    currentWeatherData.postValue(currentWeather);
    

    In your activity, you need to observe this LiveData.

    viewModel.getCurrentWeatherData().observe(this, new Observer<CurrentWeather>() {
            @Override
            public void onChanged(CurrentWeather c) {
               // Do whatever you want with c.
            }
        });