2

在学习新的 android Architecture 组件的 ViewModel 和 LiveData 时,在观察 LiveData 从数据库源更改中更改时会有些困惑,以及这将如何与 Cursor 适配器一起工作。

https://developer.android.com/reference/android/widget/CursorAdapter.html中,它说

int FLAG_REGISTER_CONTENT_OBSERVER
If set the adapter will register a content observer on the cursor 
and will call onContentChanged() when a notification comes in. Be 
careful    when using this flag: you will need to unset the current 
Cursor from the adapter to avoid leaks due to its registered 
observers. This flag is not needed when using a CursorAdapter 
with a CursorLoader.

因此,使用 cursorAdaptor 可以在更新数据库数据时获得“实时更新”。

有没有办法通过 cursorAdaptor 使用 LiveData(观察数据库数据更新)?

试图在下面的代码段中显示在哪里使用 liveData 更新光标的问题:(使用https://codelabs.developers.google.com/codelabs/android-persistence的示例)

书:

@Entity
public class Book {
    public @PrimaryKey String id;
    public String title;
}

视图模型:

public class BooksBorrowedByUserViewModel extends AndroidViewModel {

public final LiveData<List<Book>> books;

private AppDatabase mDb;

public BooksBorrowedByUserViewModel(Application application) {
    super(application);
    createDb();
    // Books is a LiveData object so updates are observed.
    books = mDb.bookModel().findBooksBorrowedByName("Mike");   //<=== this ViewModel specific to one type query statement
}

public void createDb() {
    mDb = AppDatabase.getInMemoryDatabase(this.getApplication());

    // Populate it with initial data
    DatabaseInitializer.populateAsync(mDb);
}
}

这是使用 LiveData 观察者强制重新加载光标的方法吗?

private CursorAdapter listAdapter;
private BooksBorrowedByUserViewModel mViewModel;

private void subscribeUiBooks() {
    mViewModel.books.observe(this, new Observer<List<Book>>() {
        @Override
        public void onChanged(@NonNull final List<Book> books) {

            showBooksInUi(books, mBooksTextView); //<== the sample’s code

            // if would like to update the cursorAdaptor
            //
            // ??? to requery the database and swap cursor here?
            // Cursor data = queryData(buildSqlStatement());  // build the same sql statement as used in the BooksBorrowedByUserViewModel
            // listAdapter.swapCursor(data)

        }
    });
}

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //having a list using CursorAdaptor
    ListView list = getListView();
    listAdapter = new CursorAdapter(getActivity(), null, 0)
    list.setAdapter(listAdapter);

    // Get a reference to the ViewModel for this screen.
    mViewModel = ViewModelProviders.of(this).get(BooksBorrowedByUserViewModel.class);

    subscribeUiBooks();
}
4

1 回答 1

-1

CursorAdapter 是一个老东西,你应该使用 Room + LiveData + RecyclerView。

您的数据层:

public LiveData<List<UserEntity>> getUsers() {
    return userDao.getUsers();
}

您的活动:

viewModel.getUsers().observe(this, new Observer<List<UserEntity>>() {
    @Override
    public void onChanged(@Nullable List<UserEntity> users) {
        if (users != null) {
            adapter.setUsers(users);
        }
    }
});

在适配器中:

private List<UserEntity> users = new ArrayList<>();

public void setUsers(List<UserEntity> users) {
    this.users.clear();
    this.users.addAll(users);
    notifyDataSetChanged();
}

因此,当您的活动午餐时,您应该从 Room 获取实时数据并订阅它。之后,当您向该表添加内容时,房间会自动更新观察者,因此您应该为适配器设置新数据并通知它。

应用架构指南

实时数据

房间

于 2017-08-11T16:17:59.743 回答