I have an android application which I do many realm operations. I tried to use handler threads to faster the database operations however this time I get these errors. I have reviewed similar questions but could not find out the reason.
12-17 20:07:30.826 6387 8777 W System.err: io.realm.exceptions.RealmFileException: Unable to open a realm at path '/data/data/br.com.gomus.androidapp/files/default.realm': open() failed: Too many open files. (open("/data/data/br.com.gomus.androidapp/files/default.realm") failed: Too many open files) (/data/data/br.com.gomus.androidapp/files/default.realm) in /Users/cm/Realm/realm-java-release/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 101 Kind: ACCESS_ERROR.
12-17 20:07:30.827 6387 8777 W System.err: at io.realm.internal.OsSharedRealm.nativeGetSharedRealm(Native Method)
12-17 20:07:30.827 6387 8777 W System.err: at io.realm.internal.OsSharedRealm.<init>(OsSharedRealm.java:184)
12-17 20:07:30.827 6387 8777 W System.err: at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:254)
12-17 20:07:30.828 6387 8777 W System.err: at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:244)
12-17 20:07:30.828 6387 8777 W System.err: at io.realm.RealmCache.doCreateRealmOrGetFromCache(RealmCache.java:319)
12-17 20:07:30.828 6387 8777 W System.err: at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:282)
12-17 20:07:30.828 6387 8777 W System.err: at io.realm.Realm.getDefaultInstance(Realm.java:332)
12-17 20:07:30.828 6387 8777 W System.err: at br.com.gomus.androidapp.data.local.database.LocalDatabaseImpl.findRealmObject(LocalDatabaseImpl.java:284)
12-17 20:07:30.829 6387 8777 W System.err: at br.com.gomus.androidapp.data.local.dao.schedule.SpotScheduleDaoImpl$1.run(SpotScheduleDaoImpl.java:113)
12-17 20:07:30.829 6387 8777 W System.err: at android.os.Handler.handleCallback(Handler.java:755)
12-17 20:07:30.829 6387 8777 W System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
12-17 20:07:30.829 6387 8777 W System.err: at android.os.Looper.loop(Looper.java:154)
12-17 20:07:30.830 6387 8777 W System.err: at android.os.HandlerThread.run(HandlerThread.java:61)
This is SpotScheduleDaoImp.java and line 113 corresponds to the mDatabase.findRealmObject(ScheduleCompound.class, query,
line.
@Override
public void find(Func1<RealmQuery<ScheduleCompound>, RealmQuery<ScheduleCompound>> query,
Action1<Result<List<ScheduleCompound>>> onResult) {
if (query != null) {
handlerThread = new HandlerThread("MyHandlerThreadspotscheduleDao");
handlerThread.start();
looper = handlerThread.getLooper();
Handler handler = new Handler(looper);
handler.post(new Runnable(){
@Override
public void run() {
Timber.log(Log.DEBUG, "find Thread.currentThread().getName() " + Thread.currentThread().getName());
mDatabase.findRealmObject(ScheduleCompound.class, query,
result -> {
onResult.call(Result.getData(SpotScheduleMapper.copyFromRealmResults(result.data)));
//handlerThread.quit();
},
err -> {
onResult.call(Result.getError(err));
//handlerThread.quit();
}
);
}
});
}
}
This is LocalDatabaseImpl.java and line 284 corresponds to the realm = Realm.getDefaultInstance();
command.
public <T extends RealmModel> void findRealmObject(Class<T> clazz,
Func1<RealmQuery<T>, RealmQuery<T>> filter,
Action1<Result<RealmResults<T>>> onResult,
Action1<Throwable> onError) {
Realm realm = null;
RealmResults<T> realmResults = null;
try {
realm = Realm.getDefaultInstance();
RealmQuery<T> realmQuery = filter.call(realm.where(clazz));
Timber.log(Log.DEBUG, "findRealmObject Thread.currentThread().getName() " + Thread.currentThread().getName());
realmResults = realmQuery.findAll();
if(realmResults.isValid()) {
Timber.log(Log.DEBUG, clazz.getCanonicalName() + "findRealmObject realmQuery.findAll = " + realmResults);
onResult.call(Result.getData(realmResults));
}
} catch (Exception e) {
e.printStackTrace();
onError.call(e);
}
finally
{
if(realm != null)
if(realmResults != null && realmResults.isValid())
if(!realm.isClosed()) {
realm.close();
}
}
}
What I understand is something is wrong with the closing realm instances but I do not know why. Because in finally block I close the realm instance. And before that I was closing both at the end of the try and catch blocks by checking if it is not closed before like this !realm.isClosed()
But at that time it was giving error and saying that the realm instance is already closed making it unusable. So I moved the closing part to the finally block.
This is the other stack trace.
--------- beginning of crash
12-17 20:07:31.796 6387 8776 E AndroidRuntime: FATAL EXCEPTION: MyHandlerThreadplaylistScheduleDao
12-17 20:07:31.796 6387 8776 E AndroidRuntime: Process: br.com.gomus.androidapp, PID: 6387
12-17 20:07:31.796 6387 8776 E AndroidRuntime: io.realm.exceptions.RealmError: Unrecoverable error. Too many open files in /Users/cm/Realm/realm-java-release/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 101
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at io.realm.internal.OsSharedRealm.nativeGetSharedRealm(Native Method)
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at io.realm.internal.OsSharedRealm.<init>(OsSharedRealm.java:184)
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:254)
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:244)
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at io.realm.RealmCache.doCreateRealmOrGetFromCache(RealmCache.java:319)
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:282)
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at io.realm.Realm.getDefaultInstance(Realm.java:332)
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at br.com.gomus.androidapp.data.local.database.LocalDatabaseImpl.findRealmObject(LocalDatabaseImpl.java:284)
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at br.com.gomus.androidapp.data.local.dao.schedule.PlaylistScheduleDaoImpl$1.run(PlaylistScheduleDaoImpl.java:110)
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:755)
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at android.os.Looper.loop(Looper.java:154)
12-17 20:07:31.796 6387 8776 E AndroidRuntime: at android.os.HandlerThread.run(HandlerThread.java:61)
I have troubles about closing realm instances. Any help would be appreciated.
Thanks.