为什么我会收到 java.util.ConcurrentModificationException 错误?
Why I get java.util.ConcurrentModificationException error?
我在使用这段代码时遇到问题:
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 问题和 Whosebug 中的此处,但无法解决我的问题。在我看到的所有问题中,我看到他们有一个在循环内修改的 ArrayList,但这不是我的情况。
如果你们中有人知道如何解决它,或者如果我对上面提出的概念有误,请告诉我。
提前致谢!
编辑: 我的日志控制台的堆栈跟踪(我通过 post 仅通过错误日志对其进行了简化)
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.access0(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;
}
从您的评论看来,您正在迭代的列表 examples
与支持 customAdapter
适配器的列表相同,这意味着当您 add/remove 来自 customAdapter
项目也将是 added/removed 来自 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();
}
我在使用这段代码时遇到问题:
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 问题和 Whosebug 中的此处,但无法解决我的问题。在我看到的所有问题中,我看到他们有一个在循环内修改的 ArrayList,但这不是我的情况。
如果你们中有人知道如何解决它,或者如果我对上面提出的概念有误,请告诉我。
提前致谢!
编辑: 我的日志控制台的堆栈跟踪(我通过 post 仅通过错误日志对其进行了简化)
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.access0(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;
}
从您的评论看来,您正在迭代的列表 examples
与支持 customAdapter
适配器的列表相同,这意味着当您 add/remove 来自 customAdapter
项目也将是 added/removed 来自 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();
}