近日,在APP上进行手机拍照,发现很奇怪的问题:就是在进行拍照的时候,APP会闪退,然后功能不正常;而且,闪退是非必现的——也就是多次操作肯定会出现,但并不能确定出现的时间和原因。
当时,找了各种原因,刚开始都以为是自己程序写的有问题,但由于是非必现,就可以基本上认为该结论不成立。又怀疑是高德地图的问题,但更换高德地图的SDK以后,发现问题依然存在。
在随后的几天里,进行了多次试验和相关资料搜索,最终确定是拍照过程中造成的。并有如下基本资料:部分Android机型,如oppo(鄙人的手机不幸就是oppo)、小米和三星,会在拍照时,当认为有必要时,会对Activity进行优化;优化时,会把相关Activity变量释放掉(造成闪退);当重新加载以后,该Activity里除视图相关的变量,临时变量全会置为null。
在这种情况下,就会出现APP闪退和相关Activity的功能不正常。
值得注意的是,该优化并不一定在所有机型中实现(可能其他机型也有优化,但可能优化方式和规则可能不一致)。而且,该优化对于APP工程师来说,是不可确定的。
可以实现的解决方案是:在onSaveInstanceState对临时变量进行保存;当APP闪退以后,可以在onRestoreInstanceState对临时变量进行恢复,从而保证APP的变量功能正常。
相关样例如下:
public class TestActivity extends BaseActivity {
private string mFilePath; //拍照文件返回路径,作为临时保存路径样例
//其他与视图相关的操作函数
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("mFilePath", mFilePath); //保存,方便文件恢复时使用
Log.d(TAG, "onSaveInstanceState");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
保存,方便文件恢复时使用
if (TextUtils.isEmpty(mFilePath)) {
mFilePath= savedInstanceState.getString("mFilePath");
}
Log.d(TAG, "onRestoreInstanceState");
}
//可能的拍照过程
}
通过该解决方案,APP依然会在拍照后闪退(因为闪退来自Android内部,对APP工程师来说是不可控的),但由于有临时变量保存和恢复,对于APP使用者来说,最多再次拍照即可,并不影响其太多的使用。该方案得到解决。
参考文献: