Status Update
Comments
da...@google.com <da...@google.com> #2
1. Have you saw crash in real device or only in simulators?
2. Do you use dynamic feature for language ID?
kp...@gmail.com <kp...@gmail.com> #3
Tested on Android 12 Emulator with custom executor, but cannot repro this issue.
da...@google.com <da...@google.com> #4
-
Second crash in the description is from a real device. Experienced it myself on two different Xiaomi phones, plus lots of crashes from users in the Google Play console.
-
Dynamic features are not used in the application.
As a wild guess, I have downgraded build tools from 31.0.0 to 30.0.3, compileSdk from 31 to 30, and moved all work with Language ID to the service in a separate process (just to be sure that crash can kill secondary process instead of main). This combination is in beta for 2 days by now and I don't see any SIGSEGV crashes.
ap...@google.com <ap...@google.com> #5
Hmm, I feel the crash might be something related to separate/secondary process.
I also changed compileSdk and targetSDK to 31 but still cannot repro this issue.
Description
Version used: Room 2.0.0-alpha05
Devices/Android versions reproduced on: Any
Recent deprecations influence business logic flow a lot. Example: remote server's response parsing (I think, rather common case).
Old way:
// JSONException is thrown upper, so it can be managed alltogether with HTTP response errors (for example, just ignored to use old data on unexpected response format)
public void parseResponse(final JSONObject obj, final JSONArray subObjs) throws JSONException
{
db.beginTransaction();
try {
final DBItem item = db.getDaoItem().findItem(obj.getLong("id"));
item.parseSomehow(obj); // throws JSONException on failure
final DBSubItem[] subitems = db.getDaoSubItem().findSubItems(item.getId());
db.getDaoSubItem().replaceSubItems(item.getId(), DBSubItem.parseSomehow(subObjs)); // replaces, reusing subitems with updating inner order; throws JSONException on failure
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
New way (looks worse, no exception type control - so you can throw anything and check it only in runtime):
public void parseResponse(final JSONObject obj, final JSONArray subObjs) throws JSONException
{
try {
db.runInTransaction(() -> {
... // same code as in previous example inside try...catch
return null;
});
} catch (RuntimeException e) {
if (e.getCause() instanceof JSONException) {
throw (JSONException)e.getCause();
} else {
throw e;
}
}
}
Of course, I can try to separate parsing from database interaction, but it would require at least temporary objects with no more usage (in the project's code). Additionally, sometimes next parsing steps depend on previous / storage data.
Final thoughts. Looks like runInTransaction should be recommended method in most situations, but the old way is still convenient too.