QuCoon Team
QuCoon Team

Reputation: 121

Cannot invoke observe on a background thread

I just upgraded to AndroidX and after doing that all my request. I make in background thread do not run but come up with this error.

private void getContactsList() {
    Task.callInBackground((Callable<Void>) () -> { 
     mainActivityViewModel.geContacts(contactListRequest).observe(MainActivity.this, new Observer<ContactListResponse>() {
            @Override
            public void onChanged(@Nullable ContactListResponse contactListResponse) {
                if(contactListRequest != null){
                    System.out.println("Successful");
                }
            }
        });
        return null;
    }).continueWith((Continuation<Void, Void>) task -> {
        if (task.isFaulted()) {
            Log.e(TAG, "find failed", task.getError());
        }
        return null;
    });
}



java.lang.IllegalStateException: Cannot invoke observe on a background thread
    at androidx.lifecycle.LiveData.assertMainThread(LiveData.java:443)
    at androidx.lifecycle.LiveData.observe(LiveData.java:171)
    at com.qucoon.rubies.MainActivity.lambda$getContactsList$12(MainActivity.java:887)
    at com.qucoon.rubies.-$$Lambda$MainActivity$qPAxeGqyWT-wT3M7e8stM1rX2gQ.call(lambda)
    at bolts.Task$4.run(Task.java:357)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)

Upvotes: 12

Views: 19103

Answers (4)

Ryan
Ryan

Reputation: 416

java 11:

var handler = new Handler(Looper.getMainLooper());
    handler.post(() ->getContactsList());

lambdas are available in java 8 though. var is introduced in java 11.

Upvotes: 0

Arun Yogeshwaran
Arun Yogeshwaran

Reputation: 451

Annotate your test method with @UiThreadTest

Example:

@Test @UiThreadTest
fun test_onViewCreated() {
    val view = View(appContext)
    doNothing().`when`(spyObject).initEssentials(view)

    spyObject.onViewCreated(view, null)

    verify(spyObject).init(view)
}

This worked for me

Upvotes: 2

benChung
benChung

Reputation: 406

If for Kotlin and Coroutines (with AndroidX lifecycle library 2.2.0), the following might do:

lifecycleScope.launch {
   withContext(Dispatchers.Main) {
      // Do something
   }
}

Alternatively if not for lifecycleScope and the Lifecycle 2.2.0 library, you can define your own CoroutineScope and use it as so.

Upvotes: 6

Hamza Wakrim
Hamza Wakrim

Reputation: 171

You need to execute your code in the main thread try to call getContactsList() via a handler:

Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        public void run() {
            getContactsList()
        }
    });

Upvotes: 17

Related Questions