最近項目用到了ORM資料庫Realm,功能強大,也非常友善,同時也帶來了很多奇葩的問題
比如這個異常,找了半天也沒有解決方案,經過千辛萬苦終于找到了,這裡做個記錄,防止
以後再次入坑
先看代碼
public RealmChatMessage getChatMessageSynchronous(String messageId) {
RealmChatMessage realmChatMessage = null;
try(Realm realm = Realm.getDefaultInstance()) {
realmChatMessage = realm.where(RealmChatMessage.class)
.equalTo("messageId", messageId)
.findFirst();
}
return realmChatMessage;
}
public void sendMessage(String messageId, boolean playSound) {
RealmChatMessage chatMessage = realmChatDao.getChatMessageSynchronous(messageId);
if (chatMessage != null) {
try(Realm realm = Realm.getDefaultInstance()) {
RealmChatMessage unmanagedChatMessage = realm.copyFromRealm(chatMessage);
sendMessage(unmanagedChatMessage, playSound);
}
}
}
表面上看沒啥問題,但是一運作到15行就報标題的錯,然後crash
原因是上一個方法傳過來的chatMessage說是Invalid Object,真的是百思不得其解
最後發現Realm查詢到一條資料的對象要再次使用Realm操作就要保證資料庫不能關閉,
而getChatMessageSynchronous() 裡面用了try(),()小括号中的對象會在try執行完畢
後自動釋放掉,當然對象必須實作AutoCloseable接口,最終導緻Realm資料庫關閉
是以修改後的代碼如下
public RealmChatMessage getChatMessageSynchronous(String messageId) {
return Realm.getDefaultInstance().where(RealmChatMessage.class)
.equalTo("messageId", messageId)
.findFirst();
}
public void sendMessage(String messageId, boolean playSound) {
RealmChatMessage chatMessage = realmChatDao.getChatMessageSynchronous(messageId);
if (chatMessage != null) {
try(Realm realm = Realm.getDefaultInstance()) {
RealmChatMessage unmanagedChatMessage = realm.copyFromRealm(chatMessage);
sendMessage(unmanagedChatMessage, playSound);
}
}
}
發現差別了吧,哈哈,現在又可以愉快的玩耍了