android 系统牛逼

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.ArrayListItr.next(ArrayList.java:860) at com.kalerm.android.sdk.cache.SettingInfoCache.getSettingInfoByKey(SettingInfoCache.java:134) at com.kalerm.android.sdk.cache.SettingInfoCache.getBooleanUseValueByKey(SettingInfoCache.java:163) at com.kalerm.android.launcher.ui.fragment.StdServiceMakeFragment.initButtonStatus(StdServiceMakeFragment.java:141) at com.kalerm.android.launcher.ui.fragment.StdServiceMakeFragment.initNecessaryData(StdServiceMakeFragment.java:129) at com.kalerm.android.launcher.ui.fragment.StdServiceMakeFragment_.onViewChanged(StdServiceMakeFragment_.java:118) at org.androidannotations.api.view.OnViewChangedNotifier.notifyViewChanged(OnViewChangedNotifier.java:41) at com.kalerm.android.launcher.ui.fragment.StdServiceMakeFragment_.onViewCreated(StdServiceMakeFragment_.java:80) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1313) at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2431) at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2210) at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2166) at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2067) at android.app.FragmentManagerImpl1.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 写的好啊。

你可能感兴趣的:(android 系统牛逼)