LiveData 在使用 SyncAdapter / 不同线程更新时不会观察到变化

LiveData does not observe changes when updated with SyncAdapter / different Thread

我有一个插入消息的 SyncAdapter:

public class SyncAdapter extends AbstractThreadedSyncAdapter {
    @Override
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
       messageDAO.insert(..);
    }
}

我有一个 Activity 显示这些消息的 已过滤 部分:

    protected Observer<List<MessageEntity>> messageOberserver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        this.messageOberserver = new Observer<List<MessageEntity>>() {
          @Override
          public void onChanged(List<MessageEntity> messages) {
            Log.v("tmp", "messages have changed");
            messageAdapter.setData(messages);
        }
      }

        MessageViewModel messageViewModel = ViewModelProviders.of(this).get(MessageViewModel.class);
        messageDAO.findMessagesForTopic(this.topicId).observe(this, this.messageOberserver);
  }
DAO:
    @Query("SELECT * FROM Message WHERE messageTopicId = :topicId")
    LiveData<List<MessageEntity>> messageDAO.findMessagesForTopic(String topicId);

现在的问题是观察者无法识别对消息的更改 table。如果我重新打开 activity,则会显示更改。 SyncAdapter 告诉 Activity 它应该检查更改的正确方法是什么?我读到了 postValue(),但我不知道如何使用它。 SyncAdapter 不知道 Activity.

显示的部分消息数据

--

顺便说一句。如果我从其他地方更新(不是 SyncAdapter),代码就可以工作。

您正在构建 messageOberserver [原文如此] (messageObserver)

this.messageOberserver = ...

将其传递到 observe 函数后。

observe(this, this.messageOberserver)

此时您的观察者为空。所以构造的观察者永远不会被注册,也永远不会被调用。

这可能是 运行 在另一个进程中设置您的同步适配器的结果,同步适配器服务文档默认指示该进程。尝试从 AndroidManifest.xml 中的服务中删除 android:process=":sync 或类似行。这将 运行 同步适配器与您的应用程序处于同一进程 activity。

如果您使用 Room 和多个进程,请确保启用 enableMultiInstanceInvalidation 以支持进程之间的更新通知。

        fun getDatabase(context: Context): AppDatabase {
            return synchronized(this) {
                if (!Companion::INSTANCE.isInitialized) {
                    val instance = Room.databaseBuilder(
                        context,
                        AppDatabase::class.java,
                        "media"
                    )
                        // TODO support migrations
                        .fallbackToDestructiveMigration()
                        .enableMultiInstanceInvalidation()
                        .build()
                    INSTANCE = instance
                }

                INSTANCE
            }
        }