Вы создаете новую модель представления в RetrofitHandler, поэтому ничто не наблюдает за этой моделью представления.Вместо того, чтобы RetrofitHandler полагался на ViewModel внутри, возможно, безопаснее обрабатывать обратный вызов Retrofit и публиковать данные там.вы правильно создаете ViewModel и наблюдаете за ним (назовем это ViewModel A).Затем ViewModel A создает RetrofitHandler и вызывает getData
для этого Retrofithandler.Проблема в том, что RetrofitHandler создает новую ViewModel в getData
(которую я собираюсь назвать ViewModel B).Проблема заключается в том, что результаты публикуются во ViewModel B, который ничего не наблюдает, поэтому кажется, что ничего не работает.
Простой способ избежать этой проблемы - убедиться, что только Activity / Fragment полагаетсяна (и создание) ViewModels.Больше ничего не должно знать о ViewModel.
Редактировать 2: Вот простая реализация.Я не проверял это, но это должно быть более или менее правильно.
// shouldn't know anything about the view model or the view
public class RetrofitHandler {
private ApiInterface apiInterface;
// this should probably pass in a different type of callback that doesn't require retrofit
public void getData(Callback<Unknownapi> callback) {
// only create the apiInterface once
if (apiInterface == null) {
apiInterface = ApiClient.getClient().create(ApiInterface.class);
}
// allow the calling function to handle the result
apiInterface.doGetListResources().enqueue(callback);
}
}
// shouldn't know how retrofit handler parses the data
public class SimpleViewModel extends ViewModel {
private RetrofitHandler retrofitHandler = new RetrofitHandler();
// store data in mutableSize, not with a backing field.
private MutableLiveData<Integer> mutableSize = new MutableLiveData<>();
public void handleRetrofitCall() {
// handle the data parsing here
retrofitHandler.getData(new Callback<Unknownapi>() {
@Override
public void onResponse(Call<Unknownapi> call, Response<Unknownapi> response) {
Unknownapi unknownapi = response.body();
int listSize = unknownapi.getData().size;
// set the value of the LiveData. Observers will be notified
mutableSize.setValue(listSize); // Note that we're using setValue because retrofit callbacks come back on the main thread.
Log.e("Size", Integer.toString(listSize));
}
@Override
public void onFailure(Call<Unknownapi> call, Throwable t) {
// error handling should be added here
}
});
}
// this should probably return an immutable copy of the object
public MutableLiveData<Integer> getObject() {
return mutableSize;
}
}
public class MainActivity extends AppCompatActivity {
private TextView status;
// initialize the view model only once
private SimpleViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(SimpleViewModel.class);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
status = findViewById(R.id.status);
// observe the view model's changes
viewModel.getObject().observe(this, new Observer<Integer>() {
@Override
public void onChanged(@Nullable Integer integer) {
// you should handle possibility of interger being null
Log.e("lk","f");
status.setText(Integer.toString(integer));
}
});
findViewById(R.id.retrofit).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// call the view model's function
viewModel.handleRetrofitCall();
}
});
}
}