从 onLocationMethod 获取 ConcurrentModificationException
Getting ConcurrentModificationException from onLocationMethod
我正在尝试根据服务中的以下逻辑更新 ArrayList
个位置,运行 在后台线程中通过 Runnable.I 编辑了代码以仅显示相关代码。我得到 ConcurrentModificationException
.
public static ArrayList<Location> locationPoints;
@Override
public void onLocationChanged(final Location location) {
//Log.i(TAG, "onLocationChanged: " + location);
Log.i(TAG, "onLocationChanged: " + locationPoints.size());
ArrayList<Location> alnew= locationPoints;
if(!locationPoints.isEmpty()){
for(Location l:alnew){
if(location.distanceTo(l)<=200.0f){
locationPoints.add(l);
}else{
locationPoints.add(location);
}
}
}else{
locationPoints.add(location);
}
sendLocationsToActivity(locationPoints);
}
我希望位置对象一个接一个地移动,但我看到位置对象呈指数增长。
登录onLocationChanged
的结果如下。异常来自 ArrayList
方法,但即使使用了此处给出的所有补救措施,我也无法找到解决方案。
onLocationChanged: 0
onLocationChanged: 1
onLocationChanged: 2
onLocationChanged: 4
onLocationChanged: 8
onLocationChanged: 16
onLocationChanged: 32
但如果我从 onLocationChanged
中删除所有 ArrayList
逻辑并简单地将位置对象添加到 ArrayList
,结果就是我想要的方式
onLocationChanged: 0
onLocationChanged: 1
onLocationChanged: 2
onLocationChanged: 3
onLocationChanged: 4
onLocationChanged: 5
堆栈跟踪:
FATAL EXCEPTION: main
Process: com.amreen.test, PID: 27053
Theme: themes:{default=overlay:com.resurrectionremix.pitchblack, fontPkg:com.resurrectionremix.pitchblack, com.android.systemui=overlay:com.resurrectionremix.pitchblack, com.android.systemui.headers=overlay:com.resurrectionremix.pitchblack, com.android.systemui.navbar=overlay:com.resurrectionremix.pitchblack}
java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
at com.amreen.test.MyLocationService.onLocationChanged(MyLocationService.java:146)
at com.google.android.gms.location.internal.zzk$zzb.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5458)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
ConcurrentModificationException 在使用 Iterator 遍历列表时修改列表(添加或删除元素)时发生。 for-each 循环只不过是 java.util.Iterator 的语法糖。所以这里的逻辑是这样的:
for() {
if(someCondition) {
locationPoints.add(sth);
}
}
除此之外,您还可以尝试以下操作:
for() {
if(someCondition) {
someOtherArrayList.add(sth);
}
}
一旦跳出循环,然后:
locationPoints.addAll(someOtherArrayList);
是因为ArrayList的实现,请参考文档
ArrayList document
The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.
你打赌首先得到迭代器,然后用它来添加。
示例
Iterator<Location> iter = locationPoints.iterator();
while (iter.hasNext()) {
Location location = iter.next();
if(location.distanceTo(l)<=200.0f){
iter.add(l);
}else{
iter.add(location);
}
}
我正在尝试根据服务中的以下逻辑更新 ArrayList
个位置,运行 在后台线程中通过 Runnable.I 编辑了代码以仅显示相关代码。我得到 ConcurrentModificationException
.
public static ArrayList<Location> locationPoints;
@Override
public void onLocationChanged(final Location location) {
//Log.i(TAG, "onLocationChanged: " + location);
Log.i(TAG, "onLocationChanged: " + locationPoints.size());
ArrayList<Location> alnew= locationPoints;
if(!locationPoints.isEmpty()){
for(Location l:alnew){
if(location.distanceTo(l)<=200.0f){
locationPoints.add(l);
}else{
locationPoints.add(location);
}
}
}else{
locationPoints.add(location);
}
sendLocationsToActivity(locationPoints);
}
我希望位置对象一个接一个地移动,但我看到位置对象呈指数增长。
登录onLocationChanged
的结果如下。异常来自 ArrayList
方法,但即使使用了此处给出的所有补救措施,我也无法找到解决方案。
onLocationChanged: 0
onLocationChanged: 1
onLocationChanged: 2
onLocationChanged: 4
onLocationChanged: 8
onLocationChanged: 16
onLocationChanged: 32
但如果我从 onLocationChanged
中删除所有 ArrayList
逻辑并简单地将位置对象添加到 ArrayList
,结果就是我想要的方式
onLocationChanged: 0
onLocationChanged: 1
onLocationChanged: 2
onLocationChanged: 3
onLocationChanged: 4
onLocationChanged: 5
堆栈跟踪:
FATAL EXCEPTION: main
Process: com.amreen.test, PID: 27053
Theme: themes:{default=overlay:com.resurrectionremix.pitchblack, fontPkg:com.resurrectionremix.pitchblack, com.android.systemui=overlay:com.resurrectionremix.pitchblack, com.android.systemui.headers=overlay:com.resurrectionremix.pitchblack, com.android.systemui.navbar=overlay:com.resurrectionremix.pitchblack}
java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
at com.amreen.test.MyLocationService.onLocationChanged(MyLocationService.java:146)
at com.google.android.gms.location.internal.zzk$zzb.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5458)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
ConcurrentModificationException 在使用 Iterator 遍历列表时修改列表(添加或删除元素)时发生。 for-each 循环只不过是 java.util.Iterator 的语法糖。所以这里的逻辑是这样的:
for() {
if(someCondition) {
locationPoints.add(sth);
}
}
除此之外,您还可以尝试以下操作:
for() {
if(someCondition) {
someOtherArrayList.add(sth);
}
}
一旦跳出循环,然后:
locationPoints.addAll(someOtherArrayList);
是因为ArrayList的实现,请参考文档 ArrayList document
The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.
你打赌首先得到迭代器,然后用它来添加。 示例
Iterator<Location> iter = locationPoints.iterator(); while (iter.hasNext()) { Location location = iter.next(); if(location.distanceTo(l)<=200.0f){ iter.add(l); }else{ iter.add(location); } }