возвращение объекта из Android ViewModel во фрагмент из функции обратного вызова - PullRequest
0 голосов
/ 16 декабря 2018

Я использую ViewModel в Android для получения объекта, а затем передаю его фрагменту для обновления компонентов пользовательского интерфейса.Я пытаюсь получить значение объекта асинхронно, а затем передать объект во фрагмент из функции обратного вызова.У меня уже есть ненулевое значение объекта в обратном вызове и в асинхронной задаче.У меня просто возникают проблемы при отправке объекта во фрагмент, вызвав функцию из Java-кода фрагмента.Вот фрагмент кода

Фрагмент кода ViewModel

EventViewModel.java

class EventViewModel extends AndroidViewModel {

  private OnEventListener mListener;
  Obj obj;

  //setting the listener
  public void registerOnEventListener(OnEventListener mListener){
    this.mListener = mListener;
  }

  public void getObj(){

     new Thread(new Runnable() {
        @Override
        public void run() {
          //code to obtain non-null value of object
          //& obtains non-null value here
          obj = some-non-null-value

          if(mListener != null){
                //invoke the callback
                mListener.onEvent();
          }
        }
      });
  }

   interface OnEventListener(){
     Obj onEvent();
   }

   class A implements  OnEventListener {

     @Override
     public Obj onEvent() {

       System.out.println(obj.property1); //obj is non-null here

       //....
       return obj;
   }

 }
}

Фрагмент кода fragment, к которомуЯ хочу отправить объект

EventFragment.java

public class EventFragment extends Fragment {

 private EventViewModel vm;

 @Override
 public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    vm = ViewModelProviders.of(this).get(EventViewModel.class);

    EventViewModel.OnEventListener mListener = vm. new A();
    vm.registerOnEventListener(mListener);
    vm.getObj();
    Obj o = mListener.getEvent()  //shows error as 'Incompatible Types'
                                  //so o is also null   
   }
}

Теперь я знаю, что не могу вернуть obj непосредственно в методе getObj(), он получаетВозвращается до того, как obj будет дано ненулевое значение, т.е. до завершения асинхронной задачи.При попытке описанного выше метода объект o в EventFragment всегда остается нулевым.Итак, расскажите, пожалуйста, способ отправки объекта во фрагмент EventFragment.java.Пожалуйста, укажите, если мне нужно разместить больше кода.Заранее спасибо.

1 Ответ

0 голосов
/ 16 декабря 2018

Используйте LiveData:

class EventViewModel extends AndroidViewModel {
  private MutableLiveData<Obj> liveObjects = new MutableLiveData<>();

  LiveData<Obj> getObjects() {
    return liveObjects;
  }

  public void loadObject(){
     new Thread(new Runnable() {
        @Override
        public void run() {
          Obj object = // TODO get the value

          liveObjects.postValue(object);
        }
      }).start();
  }
}

public class EventFragment extends Fragment {

 private EventViewModel vm;

 @Override
 public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    vm = ViewModelProviders.of(this).get(EventViewModel.class);

    vm.getObjects().observe(this, new Observer<Obj>() {
        @Override
        public void onChanged(@Nullable final Obj newValue) {
            // TODO something useful
        }
    });
}

Затем при необходимости вызовите loadObject() для EventViewModel, чтобы запустить фоновую работу и доставку нового объекта.

...