EDIT: it seems to be a problem related to Android Pie (api 28). Seems to work on previous versions (tested on 27, 26, 25).
I'm working at this Android code for a very long time, and I noticed that lately when I'm saving data on the disk, I receive this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.math.RoundingMode.ordinal()' on a null object reference
This is how I write data to disk
private void SaveDataToDisk() {
try {
FileOutputStream fos = this.weakActivity.get().openFileOutput(this.FILENAME, Context.MODE_PRIVATE);
if (fos != null) {
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(this.datastore);
os.close();
fos.close();
}
} catch (Exception ex) {
ErrorManager.TrapThrow(ex, this.weakActivity.get());
}
}
this.datastore is a complex object composed of multiple other object (a very large number).
This is how I read data back when needed
private void LoadDataFromDisk() {
try {
if (this.weakActivity.get().getFileStreamPath(this.FILENAME).exists()) {
FileInputStream fis = this.weakActivity.get().openFileInput(this.FILENAME);
BufferedInputStream bis = new BufferedInputStream(fis);
ObjectInputStream is = new ObjectInputStream(bis);
try {
this.datastore = (DataStore) is.readObject();
} catch (Exception ex) {
this.datastore = new DataStore();
}
is.close();
fis.close();
}
} catch (Exception ex) {
ErrorManager.TrapThrow(ex, this.weakActivity.get());
}
}
Imagine to have a fresh install of the app. The first time LoadDataFromDisk does nothing. Later in time the app writes something on the disk. When the app call LoadDataFromDisk again, it reads correctly. Then, for example, the app is relaunched: when LoadDataFromDisk is reached, and specifically
this.datastore = (DataStore) is.readObject();
I receive the error above, and falls back to a new DataStore object, in order to keep the app working.
Why not always? The data seems corrupted after has been read. I can reproduce on AVD and on my phone.
Any help appreciated
We found that this was caused by a custom DataFormatter
object (within a containing, serialized object) that relies on a java.text.DecimalFormat
. When we went to deserialize the object (sometimes but not always, but apparently dependent on how many times the containing object had been passed among Activity
extras), the entire Extras collection containing the serialized container was invalid, and crashed the app with the RoundingMode.ordinal()
NPE.
Apparently the DecimalFormat
class no longer plays well with serialization in Android 9/Pie, because in our case it was as simple as marking the containing, Serializable
object's instance of DataFormatter
as transient
and the problem vanished.
Sorry not to have a better dissection of the issue ready, but this solved our problem with this error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With