-
Notifications
You must be signed in to change notification settings - Fork 120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Many crashes on Android 10 & android 11 #237
Comments
Only had a short look and didn't try to reproduce yet (because from what you're saying, it doesn't seem very reproducible...) so for now, just observations:
|
Also, have you tried updating to the latest version (0.14.0) - should still work even if your project isn't migrated to null-safety yet? |
@vaind I will update the library and try again, I just felt lost because it's kind of hard to reproduce the same crash on my device. I will try to recheck the DBTask again and come back to you. thanks for your support |
To get back shortly to that native crash stack... It really looks weird. Seems like an exception is thrown (natively) while opening the store. For unknown reasons, this does get not caught by our exception handlers but causes an abort... We haven't ever seen this with our "plain" Android lib ever. |
@greenrobot I tried to upload app bundles, split apks, and large size apk because I thought maybe split is making this native crash, however, all my tries to reduce the crash numbers didn't help. Is there any other information I can provide to help to track this issue?. can I prevent the abort by handle all types of crashes in your native android lib? |
A wild guess: could memory pressure be a cause of such an issue? Some allocation issues that couldn't be handled on the native side? |
@vaind I don't think so, the crash also happens on note +10 which has 8GB of RAM , so if it's a memory issue I would notice it on my 4 GB emulator or 70A device |
Any chance that you could reproduce this (from Play Store) and check the logs (logcat)? Often there's interesting info before an exception is thrown. |
@greenrobot I am keep testing everyday, I will send an update here soon if I could reproduce the same crash |
@greenrobot @vaind I was able to reproduce this error again today on my emulator this is the current log
|
Error no. 11 is also known as EAGAIN ("Resource temporarily unavailable"). While trying to raise the exception, bionic seems to run into a shortage of thread specific keys... Maybe that's also the initial error. We'll also dig into this some more... |
1- it can not be reproduced always, but I will explain how this happened: There is a player that saves its playing time each 1 min to the database. My teammate used the database helper above to open the box and close it each one min and each time the user closes the player. for now, I changed the database helper and avoid opening and closing the Store each time, and opened it only once. the reason that made me think like this is this stress test results, I am not sure if I am right. the current db helper: FutureFunction<E, R> = Future<R> Function(Box<E>);
///the main goal of using this tasker is not to keep boxes open with
/// huge data which consumes more memory
class DBTask<E, R> {
DBTask({FutureFunction<E, R> onLoaded, bool shouldClose = true})
: _onLoaded = onLoaded,
_shouldClose = shouldClose {
// _currentTasks++;
_initTaskCheckers();
}
final AppLogger logger = AppLogger(tag: 'DBTask');
Store _store;
static const int _maxRetries = 3;
int _retryCount = 0;
// static int _currentTasks = 0;
final FutureFunction<E, R> _onLoaded;
final bool _shouldClose;
final Completer<R> _completer = Completer<R>();
///opens hive box
///runs your onLoad function
///waits until all work is done
///closes the box
Future<R> run() {
_preLoadChecker();
return _completer.future;
}
void _initTaskCheckers() async {}
void _preLoadChecker() async {
final bool storeReady = await _openStore();
if (storeReady == true) {
_run();
} else if (_maxRetries != _retryCount) {
await Future.delayed(const Duration(milliseconds: 200));
_preLoadChecker();
_retryCount++;
} else {
_completer.completeError('HiveTask<$runtimeType> : error timeout');
}
}
// void _close() {
// _currentTasks = max(_currentTasks--, 0);
// if (_currentTasks == 0 && _shouldClose) {
// _store?.close(); // don't forget to close the store
// }
// // logger.debug('box closed');
// }
void dispose() {
_store?.close();
}
void _run() async {
try {
final box = _store.box<E>();
final R val = await _onLoaded(box);
_completer.complete(val);
} catch (e) {
_completer.completeError('Task _run error $e');
}
}
Future<bool> _openStore() async {
final Completer<bool> storeCompleter = Completer();
if (_store != null) {
storeCompleter.complete(true);
return storeCompleter.future;
}
try {
await getApplicationDocumentsDirectory().then((Directory dir) {
if (dir?.path != null) {
_store =
Store(getObjectBoxModel(), directory: '${dir.path}/objectbox');
storeCompleter.complete(true);
} else {
storeCompleter.complete(false);
}
}).catchError((x) => storeCompleter.complete(false));
return storeCompleter.future;
} catch (ignore) {
return storeCompleter.future;
}
}
} 2- I don't think there are any logs, but I will retry to make a stress test opening and closing the store many times and I hope to reproduce it and check again. 3- the only custom thing I saw in this project is the gesture sample they copied from here Thanks for your support and I will try to dig in it more |
Yes, please keep a single store instance open for your app. There's no need to close it. When your app is shut down by the system, ObjectBox store is also closed properly. |
Is it possible that you have many of these tasks active at the same time - leading to many open stores, thus causing these out-of-resources errors. By "active", I mean after And I'll repeat myself: please use a single store and then see if this still happens. A rough idea of how you could do it with your architecture, for example you can use a global variable late final Future<Store> _store = _openStore()
Future<Store> _openStore() async => Future.sync(() async {
final dir = await getApplicationDocumentsDirectory();
return Future.value(Store(getObjectBoxModel(), directory: '${dir.path}/objectbox'));
} Then in your final box = (await _store).box<E>(); |
We have a new branch that adds a check so that a single store is only opened once, you can try it with your app by switching the dependencies:
objectbox:
git:
url: git@github.com:objectbox/objectbox-dart.git
ref: single-store-per-dir
|
Thank you guys for your time and your effort, all your solutions and suggestions were very accurate: I can confirm that the cause of this crash was opening the store many times. I will upload this version to production and if anything happened I will tell you guys. I have few things to share with you: 1- error logs are ambiguous, maybe you can print more developer-friendly crash logs as I checked again many times, it only shows Storage error and nothing more about it. 2- Maybe you can add warning logs also or prevent developers from doing this, or adding a warning of doing this on your documentation. 3- right now I can't use any null-safe libraries, the project is very old and it will take time to migrate to null-safe libraries so as a temp. fix I just moved |
We'll see if we can do sth about that
That's kinda what the branch is about - you won't be able to open multiple store instances of the same dir - throws an
Yeah, for example |
Thanks for the follow-up, I'm closing the issue now. Feel free to reopen/comment if this is still an issue. |
I am facing many crashes only after I upload the app as a bundle to google play,
Basic info
Huawei Y9 Prime 2019
Samsung Galaxy A31
Samsung Galaxy Note9
Samsung Galaxy A30s
Huawei 荣耀 8X
Samsung Galaxy A12
we have 187 users affected by this crash, I am not really sure what is the reason for this crash, would love if anybody will help us with this one. Thanks a lot.
Logs, stack trace
DATABASE TASK
The text was updated successfully, but these errors were encountered: