带有 sqlite 的 LiveData 不更新 UI
Posted
技术标签:
【中文标题】带有 sqlite 的 LiveData 不更新 UI【英文标题】:LiveData with sqlite not updating UI 【发布时间】:2021-11-15 16:49:43 【问题描述】:这是从 sqlite 数据库中获取数据作为 livedata 的代码
private LiveData<ArrayList<Message>> loadAllMessagesOfThisChat()
final MutableLiveData<ArrayList<Message>> messages= new MutableLiveData<>();
ArrayList<Message> messagesArrayList = new ArrayList<>();
SQLiteDatabase mDb = messagesDbHelper.getReadableDatabase();
String[] projection =
MessageDetails.COLUMN_SENDER_UID,
MessageDetails.COLUMN_MESSAGE,
MessageDetails.TIMESTAMP_ID,
MessageDetails.COLUMN_IMAGE_URI;
Cursor cursor = mDb.query("receiver" + receiverUID, projection, null, null, null, null, null);
int messageColumnIndex = cursor.getColumnIndex(MessageDetails.COLUMN_MESSAGE);
int timestampColumnIndex = cursor.getColumnIndex(MessageDetails.TIMESTAMP_ID);
int imageURIColumnIndex = cursor.getColumnIndex(MessageDetails.COLUMN_IMAGE_URI);
int senderUIDColumnIndex = cursor.getColumnIndex(MessageDetails.COLUMN_SENDER_UID);
while (cursor.moveToNext())
Message message = new Message();
message.setMessage(cursor.getString(messageColumnIndex));
message.setImageUrl(cursor.getString(imageURIColumnIndex));
message.setTimestamp(String.valueOf(cursor.getInt(timestampColumnIndex)));
message.setUserID(cursor.getString(senderUIDColumnIndex));
messagesArrayList.add(message);
messages.setValue(messagesArrayList);
cursor.close();
mDb.close();
return (LiveData<ArrayList<Message>>) messages;
我在 oncreate 中使用它
LiveData<ArrayList<Message>> messages=loadAllMessagesOfThisChat();
messages.observe(this, new Observer<ArrayList<Message>>()
@Override
public void onChanged(ArrayList<Message> messages)
messagesAdapter.setMessages(messages);
);
但是每当我发送一条新消息时,它都会被添加到数据库中,但更改不会反映在 UI 中,直到我重新启动我的活动
似乎观察者没有做任何事情
我正在尝试将 livedata 与 sqlite 一起使用,因为由于某些原因我无法使用空间
【问题讨论】:
【参考方案1】:在您的代码中。没有异步编程,因此您的代码同步运行。 这意味着您首先调用 setValue(),然后返回 liveData 的对象。这导致什么都不做,因为观察者在调用 setValue() 方法后正在设置。所以观察者没有观察到任何东西。
我可以想到 2 个解决方案
-
要么进行异步编程,要么在后台线程上获取数据
或者你可以直接返回 ArrayList 的值。在这种情况下,您不必使用 liveData。
【讨论】:
那么我应该在后台线程中调用 loadAllMessagesOfThisChat,然后将观察者附加到它吗? 不,不是方法。您应该添加从 sqlite 获取数据的代码,即从定义“messagesArrayList”对象到关闭数据库,但后台线程中的 setValue() 方法除外,因此它变得异步。我的观点是你应该先返回 liveData 对象,然后在它上面调用 setValue() 方法,然后它应该可以工作。【参考方案2】:不要在原生 sqllite 中使用 livedata,而是在 更新您的数据库后调用 notifyDataSetChanged()
。这将使用 最新值重新填充列表视图。
或者,您可以致电reCreate()
重新开始您的活动。
【讨论】:
以上是关于带有 sqlite 的 LiveData 不更新 UI的主要内容,如果未能解决你的问题,请参考以下文章
带有TextWatcher和LiveData的EditText中的光标位置?