我有一个聊天应用程序,其历史记录缓存在包含在RxJava运算符的Realm数据库中。 一切正常但我有时会在一组特定设备上捕获此异常:
io.realm.exceptions.RealmError: Unrecoverable error. mmap() failed: Out of memory in io_realm_internal_SharedGroup.cpp line 115
at io.realm.internal.SharedGroup.createNativeWithImplicitTransactions(SharedGroup.java)
at io.realm.internal.SharedGroup.<init>(SharedGroup.java:60)
at io.realm.Realm.<init>(Realm.java:209)
at io.realm.Realm.createAndValidate(Realm.java:600)
at io.realm.Realm.create(Realm.java:563)
at io.realm.Realm.getInstance(Realm.java:410)
at io.realm.Realm.getInstance(Realm.java:367)
at io.realm.Realm.getInstance(Realm.java:348)
at ru.ltst.happer.data.rx.OnSubscribeRealm.call(OnSubscribeRealm.java:28)
at ru.ltst.happer.data.rx.OnSubscribeRealm.call(OnSubscribeRealm.java:13)
at rx.Observable.unsafeSubscribe(Observable.java:7495)
at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
我将聊天消息写入数据库的代码:
public void addMessagesToDb(List<UIMessage> messages) {
final ArrayList<UIMessage> receivedMessages = new ArrayList<>(messages);
Observable.create(new OnSubscribeRealm<RealmMessage>(application, databaseName) {
@Override
public RealmMessage get(Realm realm) {
for (UIMessage message : receivedMessages) {
RealmMessage realmMessage = new RealmMessage();
realmMessage.setTimeMillis(message.timeMillis());
realmMessage.setText(message.text());
realmMessage.setPhotoUrl(message.photoUrl());
realmMessage.setFromOutside(message.fromOutside());
RealmDialog.addMessage(realm, message.userId(), RealmMessage.put(realm, realmMessage));
}
return new RealmMessage();
}
}).compose(this.<RealmMessage>applySchedulers())
.subscribe(new WeakSubscriberDecorator<>(new SimpleSubscriber<RealmMessage>()));
OnSubscribeRealm.java:
public abstract class OnSubscribeRealm<T extends RealmObject> implements Observable.OnSubscribe<T> {
private Context context;
private String fileName;
public OnSubscribeRealm(Context context) {
this(context, null);
}
public OnSubscribeRealm(Context context, String fileName) {
this.context = context.getApplicationContext();
this.fileName = fileName;
}
@Override
public void call(final Subscriber<? super T> subscriber) {
final Realm realm = Realm.getInstance(context);
T object;
try {
realm.beginTransaction();
object = get(realm);
realm.commitTransaction();
} catch (RuntimeException e) {
realm.cancelTransaction();
subscriber.onError(new RealmException("Error during transaction.", e));
return;
} catch (Error e) {
realm.cancelTransaction();
subscriber.onError(e);
return;
}
if (object != null) {
subscriber.onNext(object);
}
subscriber.onCompleted();
try {
realm.close();
} catch (RealmException ex) {
subscriber.onError(ex);
}
}
public abstract T get(Realm realm);
}
RealmDialog.java
静态方法,它将消息添加到历史记录
public static RealmMessage addMessage(Realm realm, String userId, RealmMessage realmMessage) {
RealmDialog realmDialog = findBy(realm, userId);
if (realmDialog != null) {
RealmMessage result = RealmMessage.put(realm, realmMessage);
realmDialog.getMessages().add(result);
return result;
}
return null;
}
我在后台线程上进行了所有查询,并在提交事务后尝试关闭所有Realm
个实例。此错误大多发生在Samsung G900H设备上。