编辑:这似乎是一个与Android (api 28)相关的问题。似乎适用于以前的版本(在27、26、25上测试)。
我在这个Android代码上工作了很长一段时间,我注意到最近当我在磁盘上保存数据时,我收到了以下错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.math.RoundingMode.ordinal()' on a null object reference我就是这样将数据写入磁盘的。
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是一个复杂的对象,由多个其他对象(很大的数目)组成。
当需要时,我就是这样读取数据的。
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());
}
}想象一下有一个新的应用程序安装。LoadDataFromDisk第一次什么也不做。稍后,应用程序会在磁盘上写一些东西。当应用程序再次调用LoadDataFromDisk时,它将正确读取。然后,例如,重新启动应用程序:当到达LoadDataFromDisk时,特别是
this.datastore = (DataStore) is.readObject();我收到上面的错误,并返回到一个新的DataStore对象,以保持应用程序的工作。
为什么不总是这样?数据在读取后似乎已损坏。我可以在AVD和我的手机上复制。
感谢你的任何帮助
发布于 2019-01-11 23:28:39
我们发现这是由依赖于DataFormatter的自定义java.text.DecimalFormat对象(在包含的序列化对象中)引起的。当我们去反序列化对象时(有时但并不总是,但显然取决于包含对象在Activity附加文件中传递了多少次),包含序列化容器的整个Extras集合无效,并使应用程序与RoundingMode.ordinal() NPE崩溃。
显然,DecimalFormat类在Android9/Pie中不再适合序列化,因为在我们的例子中,它就像标记包含、Serializable对象的DataFormatter实例为transient一样简单,问题就消失了。
很抱歉,没有更好的剖析问题,但这解决了我们的问题与这一错误。
https://stackoverflow.com/questions/53541154
复制相似问题