【问题标题】:Cannot invoke observe on a background thread无法在后台线程上调用观察
【发布时间】:2019-02-15 00:27:08
【问题描述】:

我刚刚升级到AndroidX,之后我提出了所有要求。我让后台线程不运行,但出现此错误。

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)

【问题讨论】:

  • 发布您的相关代码
  • 我已经做到了@Raghunandan
  • 检查您对Observer 的导入,也许从MV 你应该postValue(...)?此方法从其他线程发布,setValue(...) 从主线程发布。
  • 代码看起来不错。您需要发布更多相关代码。您设置contactList的线程部分
  • Task.callInBackground((Callable&lt;Void&gt;) () ... 也许这里隐藏了问题? Cannot invoke observe on a background thread

标签: android androidx


【解决方案1】:

您需要在主线程中执行您的代码尝试通过处理程序调用getContactsList()

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

【讨论】:

    【解决方案2】:

    如果对于 Kotlin 和 Coroutines(使用 AndroidX 生命周期库 2.2.0),可能会执行以下操作:

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

    或者,如果不是 lifecycleScope 和 Lifecycle 2.2.0 库,您可以定义自己的 CoroutineScope 并照此使用。

    【讨论】:

    • 很好,这可以帮助我找出我的问题。您还可以为启动构建器launch(Dispatchers.Main) {...} 指定调度程序,因为未指定的默认调度程序是Dispatchers.Default
    • 我必须将 implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.0" 添加到我的 build.gradle 中,以便 lifecycleScope 在我的生命周期所有者组件中可用
    【解决方案3】:

    使用 @UiThreadTest 注释您的测试方法

    例子:

    @Test @UiThreadTest
    fun test_onViewCreated() {
        val view = View(appContext)
        doNothing().`when`(spyObject).initEssentials(view)
    
        spyObject.onViewCreated(view, null)
    
        verify(spyObject).init(view)
    }
    

    这对我有用

    【讨论】:

      【解决方案4】:

      Java 11:

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

      lambdas 在 java 8 中是可用的。 var 在 java 11 中引入。

      【讨论】:

        猜你喜欢
        • 2019-02-15
        • 1970-01-01
        • 1970-01-01
        • 2015-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多