2022年11月15日10:46:07
感叹下 Android 的google工程师真牛逼啊。
今天发现了一个bug,在一个非常老的项目里,运行了三四年,都没崩溃。
起因是:
[b.v]203
[u.o]Android 10;A227---------------------Crash Device End---------------------
java.util.ConcurrentModificationException
at java.util.ArrayList1.run(FragmentManager.java:742)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7397)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
===============Crash End===============
一个数组修改读取异常。应该是在修改的时候,在遍历读取,导致崩溃。
一个看起来没啥毛病的一段代码:
public SettingInfoItem getSettingInfoByKey(String key) {
SettingInfoItem settingInfoItem = new SettingInfoItem();
if (settingInfoItemList == null) {
settingInfoItemList = SettingInfoItemManager.getInstance(mContext).find();//从数据库读
}
for (SettingInfoItem item : settingInfoItemList) {
if (key.equals(item.getSetting_key())) {
//use没有值的时候显示的时候就用default
if (TextUtils.isEmpty(item.getUse_value())) {
item.setUse_value(item.getDefaults_value());
}
settingInfoItem = item;
break;
}
}
//这里说明这个key是新增的,不在已经初始化好的db当中,我们要构造出来
if (settingInfoItem.get_id() == 0) {
LogUtil.e("fuck, id is not in db load assets, key is " + key);
if (assets == null) {
assets = SettingInfoInitManager.getInstance(mContext).getSettingInfoFromAssets();//从config文件硬编码读
}
if (assets.containsKey(key)) {
settingInfoItem.setDefaults_value(assets.get(key));
settingInfoItem.setUse_value(assets.get(key));
}
settingInfoItem.setSetting_key(key);
settingInfoItemList.add(settingInfoItem);//把它加到缓存中去
}
return settingInfoItem;
}
实际上会造成,如果数据库没有数据,新增一个id为0的item项,会造成重复的add进list。
结果就是。在一些轮询设置读取中,每次都会新增一个id为0 ,然而key一样的数据,进入list。
这个*settingInfoItemList * 就一直在自增,设备不关机,就没四五秒增加三四条。居然一直没崩溃,用了好几年都没事。
感叹一句,google工程师牛逼,ArrayList 写的好啊。
网友评论