Solution 1 :
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.
}
});
Problem :
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) {
}
}
Comments
Comment posted by Amir Hossein
Thanks, it works with LiveData but is there other way in the first method to ask it to wait ?
Comment posted by Loremar Marabillas
@AmirHossein I can think of two ways. One is to use the synchronous call for Retrofit wherein you won’t need to override onResponse. And two, you can use CountDownLatch wherein you await until countdown is called inside onResponse. Either ways, you will be blocking the UI thread which is something that you shouldn’t do. The LiveData approach is best practice and is the recommended approach.
Comment posted by Amir Hossein
thanks , I think as you Mentioned here Live Data is the best .