6
votes

Impossible d'appeler observer sur un thread d'arrière-plan

Je viens de passer à AndroidX et après avoir fait cela, toute ma demande. Je fais en arrière-plan le thread ne fonctionne pas mais je trouve cette erreur.

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)


8 commentaires

publier votre code pertinent


J'ai fait ça @Raghunandan


Vérifiez votre importation de Observer et peut-être de MV devriez-vous postValue (...) ? Cette méthode post depuis un autre fil et setValue (...) depuis le fil principal.


le code semble correct. vous devez publier un code plus pertinent. la partie de filetage où vous définissez contactList


Task.callInBackground ((Callable ) () ... Peut-être cache ici le problème? Impossible d'appeler observer sur un thread d'arrière-plan


Cela fonctionnait avant de passer à Android X @YaroslavOvdiienko


si vous utilisez viemodel et que vous observez vos données, cela devrait se produire sur le thread principal. si vous souhaitez obtenir la liste de contacts qui devrait se produire sur un fil différent. vous postvaluez alors sur vos données et observez ces changements dans votre activité. developer.android.com/topic/libraries/architecture/livedata


@Raghunandan Oui merci j'ai appliqué ce que vous avez dit et ça marche bien


3 Réponses :


5
votes

Vous devez exécuter votre code dans le thread principal, essayez d'appeler getContactsList () via un gestionnaire:

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


0 commentaires

3
votes

Si pour Kotlin et Coroutines (avec la bibliothèque de cycle de vie AndroidX 2.2.0), ce qui suit pourrait faire:

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

Sinon, sinon pour lifecycleScope et le cycle de vie 2.2 .0, vous pouvez définir votre propre CoroutineScope et l'utiliser comme tel.


1 commentaires

Bien, cela m'aide à comprendre mon problème. Vous pouvez également spécifier le répartiteur pour le lancement du générateur launch (Dispatchers.Main) {...} car celui par défaut sans spécification est Dispatchers.Default .



0
votes

Annotez votre méthode de test avec @UiThreadTest

Exemple:

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

    spyObject.onViewCreated(view, null)

    verify(spyObject).init(view)
}

Cela a fonctionné pour moi


0 commentaires