Comments (35)
OK, so I ended up not doing this. Instead, I overrode the method onBeforeClusterRendered to give a clue to the user, that in that cluster, there's something going on.
The problem with my logic above, is that when it's zoomed out, no clusters will be rendered, and all icons will be drawn (mine has about 200)
But still, just in case you have a use-case for this scenario...
from android-maps-utils.
Thanks for the report! Is this easy to reproduce?
This is a bit odd – I wonder why removeAll() gets called. Perhaps we need to take a copy of the cluster set at the beginning of rendering.
from android-maps-utils.
In my case, I find that it can be reproduce, if you override the method shouldRenderAsCluster and return false all the time
from android-maps-utils.
I get the same issue but I can't say why I get it and can't reproduce it
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806)
at java.util.HashMap$KeyIterator.next(HashMap.java:833)
at java.util.AbstractSet.removeAll(AbstractSet.java:110)
at com.google.maps.android.clustering.view.DefaultClusterRenderer$RenderTask.run(DefaultClusterRenderer.java:382)
at java.lang.Thread.run(Thread.java:841)
Actually, I'm quite surprised to see only two people here that have encountered this issue, it happens quite often when you play to zoom/un-zoom on a map with Clusters.
from android-maps-utils.
Yeah I am seeing this as well. I thought it was something I was doing but that was not the case. An progress or updates? I wrote #74 before I realized there was already an open ticket.
from android-maps-utils.
1.) Not that it matters, - my marker locations are trickling in (coming from a network call)
I think this does actually matter, and is likely what triggers this bug. I'll investigate.
from android-maps-utils.
I also have encountered the same issue, I got an ACRA error log report from one of my app.
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806)
at java.util.HashMap$KeyIterator.next(HashMap.java:833)
at java.util.AbstractSet.removeAll(AbstractSet.java:110)
at com.google.maps.android.a.b.l.run(DefaultClusterRenderer.java:383)
at java.lang.Thread.run(Thread.java:841)
from android-maps-utils.
I also got the same error and have debugged the issue a bit more.
What happens is that the RenderTask calls the method markerModifier.waitUntilFree(); before it removes all new markers from the markersToRemove Set. Unfortunately the waitUntilFree method returns too early and the newMarkers Set is modified while being used in the removeAll method.
waitUntilFree returns too early, because the isBusy() method in the MarkerModifier will return false as soon as it's Queues are empty, i.e. when the last modifier task has been started. The task however is still running and in the case of the CreateMarkerTasks will modify the newMarker Set of the RenderTask.
=> MarkerModifier.isBusy() should return false only after all it's task have been finished
I used an ugly workaround in the closed source project I'm currently working on, which uses a counter and a callback for the CreateMarkerTasks to fix the isBusy method. Not pretty and I currently don't have time to provide a proper fix for this, but I hope my analysis helps a bit.
from android-maps-utils.
I have the same issue. I also get the markers from a network call. I'm writing this because i'd like to launch my app soon and with this bug it's impossible to publish the app ;-)
from android-maps-utils.
Agreed, marker cluster is 100% unusable until this is fixed.
from android-maps-utils.
I also am experiencing this issue. I hadn't seen the issue in my testing phase, and just launched my app last night. First time I used it today, this issue occurred.
from android-maps-utils.
I have add "synchronized" to the run method in RenderTask class. No problem since.
public synchronized void run()
from android-maps-utils.
Interesting. If that actually fixes it, then there's a bug somewhere else, since only one RenderTask should be running at a time.
from android-maps-utils.
got the same issue today
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806)
at java.util.HashMap$KeyIterator.next(HashMap.java:833)
at java.util.AbstractSet.removeAll(AbstractSet.java:110)
at com.google.maps.android.clustering.view.DefaultClusterRenderer$RenderTask.run(DefaultClusterRenderer.java:383)
at java.lang.Thread.run(Thread.java:841)
from android-maps-utils.
The same issue - it happens more often when I don't have any clusters, just plain markers. "synchronized" in RenderTask didn't fix it.
from android-maps-utils.
I believe I'm against the same problem, although it's manifesting in a different way: markers sometimes disappear after zooming in, out and in again. After investigating the code, I came to the same conclusion as rgeldmacher: isBusy() is not reporting the full truth. Here's a prettified debug log:
05-26 21:11:40.239 MyRenderer.onClustersChanged onClustersChanged: size 1
05-26 21:11:40.239 MarkerModifier.performNextTask perform mOnScreenCreateMarkerTasks
05-26 21:11:40.269 MarkerModifier.waitUntilFree finished waiting until free
05-26 21:11:40.269 RenderTask.run markersToRemove: size 2, newMarkers: size 0, CreateMarkerTasks: added 1
05-26 21:11:40.269 RenderTask.run - marker to remove: 1140931912
05-26 21:11:40.269 RenderTask.run - marker to remove: 1143961664
05-26 21:11:40.389 MyRenderer.onClusterItemRendered rendering marker: 1143961664
05-26 21:11:40.389 CreateMarkerTask.perform add item to newMarkers: 1143961664
05-26 21:11:40.389 MarkerModifier.waitUntilFree is busy, waiting...
05-26 21:11:40.389 MarkerModifier.performNextTask perform mOnScreenRemoveMarkerTasks
05-26 21:11:40.389 MyMarkerManager remove marker: 1143961664
05-26 21:11:40.389 MarkerModifier.performNextTask perform mRemoveMarkerTasks
05-26 21:11:40.399 MyMarkerManager remove marker: 1140931912
05-26 21:11:40.399 MarkerModifier.waitUntilFree finished waiting until free
As a workaround, I've copied the entire DefaultClusterRenderer.java
into my project, changed the package, and modified MarkerModifier.performNextTask
to remove the task from the queue only after performing it.
private void performNextTask() {
if (!mOnScreenRemoveMarkerTasks.isEmpty()) {
removeMarker(mOnScreenRemoveMarkerTasks.peek());
mOnScreenRemoveMarkerTasks.remove();
} else if (!mAnimationTasks.isEmpty()) {
mAnimationTasks.peek().perform();
mAnimationTasks.remove();
} else if (!mOnScreenCreateMarkerTasks.isEmpty()) {
mOnScreenCreateMarkerTasks.peek().perform(this);
mOnScreenCreateMarkerTasks.remove();
} else if (!mCreateMarkerTasks.isEmpty()) {
mCreateMarkerTasks.peek().perform(this);
mCreateMarkerTasks.remove();
} else if (!mRemoveMarkerTasks.isEmpty()) {
removeMarker(mRemoveMarkerTasks.peek());
mRemoveMarkerTasks.remove();
}
}
I'm not sure this is the right and cleanest fix, but the symptom seems to have gone away.
from android-maps-utils.
Had the same issue today. Still no fix for this?
from android-maps-utils.
Getting
06-10 21:18:08.644 28224-28549/myapp.app E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-4561
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:792)
at java.util.HashMap$KeyIterator.next(HashMap.java:819)
at java.util.AbstractSet.removeAll(AbstractSet.java:110)
at myapp.CustomClusterRenderer$RenderTask.run(CustomClusterRenderer.java:387)
at java.lang.Thread.run(Thread.java:856)
My CustomClusterRenderer isn't that custom BTW.
from android-maps-utils.
Update regarding disappearing markers:
When the the markers disappear, "onClusterItemRendered" is called in the ClusterRenderer as usual, and the marker is non-null. But when I zoom in/out to cause it to reappear (actually render), the marker is now null and hits onBeforeClusterItemRendered first.
from android-maps-utils.
Got the same error a few minutes ago. I actually never got it before.
I was asking myself if its not possible using a ConcurrentSkipListSet, that could solve the problem and because the basic operations in O(log n). So if the Cluster is not too big you should be fine. What do you all think about that ?
from android-maps-utils.
We are getting a few of these too, a fix would be great.
from android-maps-utils.
I have the same issue:
FATAL EXCEPTION: Thread-4737
Process: pt.inm.prd.android.twork, PID: 11369
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806)
at java.util.HashMap$KeyIterator.next(HashMap.java:833)
at java.util.AbstractSet.removeAll(AbstractSet.java:110)
at com.google.maps.android.clustering.view.DefaultClusterRenderer$RenderTask.run(DefaultClusterRenderer.java:384)
at java.lang.Thread.run(Thread.java:841)
When is called:
markersToRemove.removeAll(newMarkers);
from android-maps-utils.
FWIW I'm consistently seeing the same thing when I return false in shouldRenderAsCluster and then zoom out the map
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806)
at java.util.HashMap$KeyIterator.next(HashMap.java:833)
at java.util.AbstractSet.removeAll(AbstractSet.java:110)
at com.google.maps.android.clustering.view.DefaultClusterRenderer$RenderTask.run(DefaultClusterRenderer.java:383)
at java.lang.Thread.run(Thread.java:841)
from android-maps-utils.
Same issue here!
from android-maps-utils.
I think ento and rgeldmacher have found the root cause : Each task in queue should be performed completely before being removed from queue.
The queue.poll().perform() should be fixed.
from android-maps-utils.
Same here. Never got this bug before but now during final testing I get it when playing around with the map, where there are no clusters at all, just normal markers.
W/dalvikvm( 2288): threadid=44: thread exiting with uncaught exception (group=0x41d9c700)
E/AndroidRuntime( 2288): FATAL EXCEPTION: Thread-20951
E/AndroidRuntime( 2288): java.util.ConcurrentModificationException
E/AndroidRuntime( 2288): at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806)
E/AndroidRuntime( 2288): at java.util.HashMap$KeyIterator.next(HashMap.java:833)
E/AndroidRuntime( 2288): at java.util.AbstractSet.removeAll(AbstractSet.java:110)
E/AndroidRuntime( 2288): at com.google.maps.android.a.b.b$f.run(DefaultClusterRenderer.java:384)
E/AndroidRuntime( 2288): at java.lang.Thread.run(Thread.java:841)
Not easy to recreate this bug though.
from android-maps-utils.
I've found potential problem in the code:
Method com.google.maps.android.clustering.view.DefaultClusterRenderer.MarkerModifier.isBusy()
works with protected data queues, like mCreateMarkerTasks
, mOnScreenCreateMarkerTasks
, ... It's called 3 times, and 2 of them are protected with lock, however here:
public void waitUntilFree() {
while (isBusy()) {
lock is not used. And waitUntilFree()
is also called without locking. So I'd recommend to wrap return with the lock:
public boolean isBusy() {
lock.lock();
try {
return ...;
} finally {
lock.unlock();
}
}
As far as i understood everybody have crashes in line markersToRemove.removeAll(newMarkers);
If RenderTask.run()
can run only in a one thread at the same time, then markersToRemove
(and member mMarkers
that holds reference on the same set-object at that moment of time) is saved from threading issues.
However local Set<MarkerWithPosition> newMarkers
can cause problems. It is shared with CreateMarkerTask
instances and is modified inside its perform()
method while called from UI thread on each MarkerModifier.handleMessage()
call.
In this conditions we can get ConcurrentModificationException in this case:
markerModifier.waitUntilFree();
returns control toRenderTask
's thread too early due to not thread save implementation ofMarkerModifier.isBusy()
RenderTask
's thread starts execution ofmarkersToRemove.removeAll(newMarkers);
- VirtualMashine switches control to UI thread
MarkerModifier.handleMessage()
is invoked and tries to modify shared setnewMarkers
inCreateMarkerTask.perform()
Summary. Those who had issues, try to add lock to isBusy()
and check.
from android-maps-utils.
Same issue: ConcurrentModificationException when removeAll() called
from android-maps-utils.
Hi,
I'm having this same issue when just zooming out fast in the map when there are a lot of clusters/markers visible.
09-03 12:04:15.425 6231-8568/co.vmob.outofthebox W/dalvikvm﹕ threadid=30: thread exiting with uncaught exception (group=0x4157bba8)
09-03 12:04:15.425 6231-8568/co.vmob.outofthebox E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-22949
Process: co.vmob.outofthebox, PID: 6231
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806)
at java.util.HashMap$KeyIterator.next(HashMap.java:833)
at java.util.AbstractSet.removeAll(AbstractSet.java:110)
at com.google.maps.android.clustering.view.DefaultClusterRenderer$RenderTask.run(DefaultClusterRenderer.java:383)
at java.lang.Thread.run(Thread.java:841)
I'm using a custom cluster renderer that only adds titles to the clusters and markers (and a custom icon to the markers as well):
private Context mContext;
public VenuesClusterRenderer(Context context, GoogleMap map, ClusterManager<VenueClusterItem> clusterManager) {
super(context, map, clusterManager);
mContext = context;
}
@Override
protected void onBeforeClusterRendered(Cluster<VenueClusterItem> cluster, MarkerOptions markerOptions) {
super.onBeforeClusterRendered(cluster, markerOptions);
// Add title to the cluster indicating exactly how many venues are inside it
markerOptions.title(mContext.getString(R.string.venues_cluster_title, cluster.getSize()));
}
@Override
protected void onBeforeClusterItemRendered(VenueClusterItem item, MarkerOptions markerOptions) {
super.onBeforeClusterItemRendered(item, markerOptions);
// Add title to the venue indicating its address
markerOptions.title(item.getVenue().getAddress());
// Set a custom venue marker
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_map_marker));
}
from android-maps-utils.
I'm seeing the same issue reported many time my crash reporting service (BugSense)
I will try the isBusy() workaround suggested here and hope the problem will go ago until a proper fix comes out
Edit: Oh, wait, isBusy belongs to MarkerModifier which is an internal private class I can't override without modifying the library code. I'd rather not touch the library.
Any workarounds anyone can suggest ?
from android-maps-utils.
I'm guessing this still hasn't been fixed
from android-maps-utils.
@dimomite fantastic - that looks like the problem. would you send a pull request?
from android-maps-utils.
Released as 0.3.2
- can you all try this new version and see if you still see the problem?
from android-maps-utils.
It sounds like it has been fixed. Four phones ran my application for about 60 hours without exception which was impossible before this fix!
from android-maps-utils.
I think you are right @kashoory. I don't see that crash happening anymore.
from android-maps-utils.
Related Issues (20)
- Add support for Advanced Markers HOT 1
- Ability to specify `anchor` marker option for `ClusterItem`
- Refdocs stuck at v3.4.0 HOT 3
- Change documentation link to GitHub page HOT 1
- Set documentation title as "android-maps-utils" HOT 1
- A lot of unnecessary warnings HOT 1
- Add StreetViewSource parameter to fetchStreetViewData HOT 2
- Remove outdated CHANGELOG.md file HOT 2
- Add kml layer in compose HOT 1
- Creating Kotlin demos for android-maps-utils
- Add Header Check to android-maps-utils
- Improve javadoc descriptions to marker clustering algorithms
- java.lang.IllegalArgumentException : Unmanaged descriptor HOT 3
- Android Map development encountered Google Map deadlock issue: HOT 3
- Incorrect operation of the marker information window HOT 3
- Multiple google api keys (MAPS_API_KEY) per Application HOT 1
- Odd cluster behavior during clustering HOT 1
- Add AdvancedMarkerManager Collection HOT 2
- setOnMarkerDragListener does not report marker drag event HOT 2
- Google Maps is not loading on Android 8 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from android-maps-utils.