1

I'm using multiple MutableLiveData on an MVVM architecture. on the ViewModel, I post the objects but the fragment is not resumed. when the fragment has resumed the observers get the MutableLiveData but not in the order I post them. How can I force an order of getting the MutableLiveData?

ViewModel:

void foo(){

first_MutableLiveData.post(newData)

second_MutableLiveData.post(newData)

}

fragment:

initView(){

first_MutableLiveData.observe(this,()->{
"getting called second"})

second_MutableLiveData.observe(this,()->{
"getting called first"})

}
majid ghafouri
  • 787
  • 2
  • 7
  • 23
ohad.k.k
  • 11
  • 4
  • Where are you registering observe in fragment? – M D Oct 10 '19 at 12:02
  • In the onViewCreated – ohad.k.k Oct 10 '19 at 12:03
  • your fragment messages are switched. is this intentional? – Rahul Oct 10 '19 at 12:10
  • the messages are switched by purpose in order to indicate that the first_MutableLiveData is getting the data second and the second_MutableLiveData getting the data first. it's only to illustrate to you what happens – ohad.k.k Oct 10 '19 at 12:13
  • Just pass a MainThreadExecutor in the class where foo() is and execute with setValue instead of postValue on the MainThread. You can't force it. – Yavor Mitev Oct 10 '19 at 12:33

2 Answers2

1

You can't force what you want. As you can see from the code they are posting the result to the MainThread by calling:

ArchTaskExecutor.getInstance()  

So now one would bother to support the syncronization between two different LiveData objects. It is your job do do so. It is a corner case.

Just use setValue, instead of postValue directly on the MainThread. Here is an example.

public class MainThreadExecutor implements Executor {

    private final Handler handler = new Handler(Looper.getMainLooper());

    @Override
    public void execute(Runnable runnable) {
        handler.post(runnable);
    }
}

public class YourClass {

    MutableLiveData first_MutableLiveData = new MutableLiveData<Data>();
    MutableLiveData second_MutableLiveData = new MutableLiveData<Data>();


    private final Executor executor;

    public YourClass(Executor executor) {
        this.executor = executor;
    }


    void foo(){

        executor.execute(new Runnable(){
            @Override
            public void run() {
                first_MutableLiveData.setValue(newData);
                second_MutableLiveData.setValue(newData);
            }
        });

    }

}
Yavor Mitev
  • 1,363
  • 1
  • 10
  • 22
0

So apparently when I changed the observer's order on the fragment they arrived in the order I needed them to be. Thanks everyone for the quick response!

ohad.k.k
  • 11
  • 4
  • Actually, it can sometimes be in-order. They don't switch. Executors are being used internally and they run in parallel. The answer from Mitev is correct. You need to use `setValue` instead of `postValue` but setValue can only be called on MainThread. – Rahul Oct 10 '19 at 13:19