最近公司的项目经常发生一个奇怪的bug,fragment中的一个成员变量device经常发生空指针异常,但是这个device是从单例中拿到的对象,理论上不论发生何种情况从单例中拿到的对象都不应该为空。
在正常的流程里找了很久这个bug发生的原因未果,后来想是不是app被系统回收资源之后发生的异常,经过一系列的debug发现,单例中的拿到的对象依旧不为空,只是成员变量device为空。
解决:深究发现device是在fragment的构造函数中被赋值,在app回收中重新进入app所走的流程中都没有对device重新赋值,造成device为空发生crash。对对象进行恢复后虽然不发生crash了,但是ui上显示有些问题。因为是对线上的代码做一次修复,出于减少代码逻辑上的修改的考虑,不对代码进行大量的修改,所以使用折中的办法解决此问题。在fragment所依托的activity中,当onSaveInstanceState()发生时使用bundle记录发生异常情况,在onCreate中判断是否有异常发生,若发生异常则finish,并重启一个新的activity。
结论:构造fragment实例一定要使用newInstance,使用bundle来对fragment的成员变量赋值。注意所使用的数据在异常情况下是否能被恢复,若不能则需要使用如onSaveInstanceState()、onRestoreInstanceState()、onCreate()等方法来保存或恢复原有数据。