【问题标题】:Why I get java.util.ConcurrentModificationException error?为什么我得到 java.util.ConcurrentModificationException 错误?
【发布时间】:2015-06-05 00:11:43
【问题描述】:

我在处理这段代码时遇到了问题:

protected void onPostExecute(ArrayList<Example> examples){
        for(Example i : examples)
        {
            customAdapter.add(i);
        }
        listExamples.setAdapter(customAdapter);
    }

其中 listExamples 是我的 mainActivity 布局中的 ListView

它给我的错误是java.util.ConcurrentModificationException 错误。我知道当你修改循环内的 ArrayList 时会发生这种情况,但在这里我并没有真正修改我的 ArrayList 值。我只是将 Example 的对象添加到我的 CustomAdapter 中(它不在循环中迭代)。

注意:如您所见,此代码包含在我的 AsynkTask 方法的 onPostExecute 部分中。

我查看 Internet 问题和 Stackoverflow 此处的问题,但无法解决我的问题。在我看到的所有问题中,我看到他们有一个 ArrayList,他们正在循环内修改,但这不是我的情况。

如果你们中有人知道如何解决它,或者我对上面提到的概念有误,请告诉我。

提前致谢!

编辑:我的日志控制台的堆栈跟踪(我通过仅发布错误日志来简化它)

06-05 02:22:31.891  24678-24678/ccom.example.user.project E/﹕ appName=com.example.user.project, acAppName=/system/bin/surfaceflinger
06-05 02:22:31.891  24678-24678/com.example.user.project E/﹕ 0
06-05 02:22:31.891  24678-24678/com.example.user.project E/﹕ appName=com.example.user.project, acAppName=/system/bin/surfaceflinger
06-05 02:22:31.891  24678-24678/com.example.user.project E/﹕ 0
06-05 02:22:32.953  24678-24678/com.example.user.project E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.user.project, PID: 24678
    java.util.ConcurrentModificationException
            at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
            at com.example.user.project.MainActivity$chargeExample.onPostExecute(MainActivity.java:192)
            at com.example.user.project.MainActivity$chargeExample.onPostExecute(MainActivity.java:131)
            at android.os.AsyncTask.finish(AsyncTask.java:632)
            at android.os.AsyncTask.access$600(AsyncTask.java:177)
            at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
            at android.os.Handler.dispatchMessage(Handler.java:110)
            at android.os.Looper.loop(Looper.java:193)
            at android.app.ActivityThread.main(ActivityThread.java:5333)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
            at dalvik.system.NativeStart.main(Native Method)

编辑2:这是我的asynktask方法和doInBackground()中的代码

class chargeExample extends AsyncTask<Void, Integer, ArrayList<Example>> {
        protected void onPreExecute(){
        }
        protected ArrayList<Example> doInBackground(Void... params) {

            String url = "url of my GET method of my API REST";

            HttpGet method = new HttpGet(url);

            method.setHeader("content-type", "application/json");

            try{
                HttpResponse response = httpClient.execute(method);
                String responseString = EntityUtils.toString(response.getEntity());
                JSONArray responseJSON = new JSONArray(responseString);
                for(int i=0; i<responseJSON.length(); i++){
                    JSONObject object = responseJSON.getJSONObject(i);

                    int idMain = object.getInt("idMain");
                    String date = object.getString("date");
                    String name = object.getString("name");
                    double value = object.getDouble("value");
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-dd");
                    Date datePar = sdf.parse(date);

                    examp.add(new Example(idMain, datePar, name, value));
                }
            }catch(Exception ex){
                Log.e("ServicioRest", ex.toString());
            }
            return examp;
        }

【问题讨论】:

  • 如果您在另一个线程上修改列表,可能会出现此错误。防止这种情况的一种方法是访问synchronized 块中的列表,例如:synchronized(examples){...},您可能必须对customAdapter 执行相同操作。
  • 您的堆栈跟踪如何显示同一 onPostExecute() 方法的两次不同调用,但您发布的代码不包含任何递归调用,并且无论如何都不足以解释行号在跟踪?简化问题很好,但发布任何伴随您发布的问题的错误。
  • @Error404,该解释与实际的堆栈跟踪不一致,但如果您将行附近的代码提供给我们,也许我们可以弄清楚发生了什么真正 131.跨度>
  • @Error404 您需要在每次访问该对象时对其进行同步,而不仅仅是在该方法中。
  • 您在创建customAdapter 对象时是否使用了examp 列表?如果是这样,这行customAdapter.add(i); 实际上会修改适配器使用的下划线ArrayList&lt;&gt; (examp),这意味着您在迭代列表时正在修改它,因此会出现异常。

标签: java android arraylist android-asynctask


【解决方案1】:

从您的 cmets 看来,您正在迭代 examples 的列表与支持 customAdapter 适配器的列表相同,这意味着当您从 customAdapter 添加/删除项目时,项目也将被添加/从examples 引用的列表中删除。在这种情况下,为了防止异常,您可以执行以下操作:

class chargeExample extends AsyncTask<Void, Integer, ArrayList<Example>> {
    protected void onPreExecute(){
    }
    protected ArrayList<Example> doInBackground(Void... params) {
        ArrayList<Example> newList = new ArrayList<Example>();
        String url = "url of my GET method of my API REST";

        HttpGet method = new HttpGet(url);

        method.setHeader("content-type", "application/json");

        try{
            HttpResponse response = httpClient.execute(method);
            String responseString = EntityUtils.toString(response.getEntity());
            JSONArray responseJSON = new JSONArray(responseString);
            for(int i=0; i<responseJSON.length(); i++){
                JSONObject object = responseJSON.getJSONObject(i);

                int idMain = object.getInt("idMain");
                String date = object.getString("date");
                String name = object.getString("name");
                double value = object.getDouble("value");
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-dd");
                Date datePar = sdf.parse(date);

                newList.add(new Example(idMain, datePar, name, value));
            }
        }catch(Exception ex){
            Log.e("ServicioRest", ex.toString());
        }
        return newList;
    }

onPostExecute(...)

protected void onPostExecute(ArrayList<Example> examples){
    for(Example i : examples)
    {
        customAdapter.add(i);
    }
    customAdapter.notifyDataSetChanged();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 2016-11-25
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多