npx cap doctor
💊 Capacitor Doctor 💊
Latest Dependencies:
@capacitor/cli: 5.5.1
@capacitor/core: 5.5.1
@capacitor/android: 5.5.1
@capacitor/ios: 5.5.1
Installed Dependencies:
@capacitor/ios: not installed
@capacitor/cli: 5.5.1
@capacitor/core: 5.5.1
@capacitor/android: 5.5.1
[success] Android looking great! 👌
Platform(s)
Android (v8 to 14)
Current Behavior
When the application, which uses the Capacitor Geolocation plugin, is put into the background for a few minutes and then brought back to the foreground, the app crashes with a java.util.ConcurrentModificationException. This exception occurs in the GeolocationPlugin.handleOnResume method, as detailed in the stack trace provided.
java.util.ConcurrentModificationException: null
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1441)
at java.util.HashMap$ValueIterator.next(HashMap.java:1470)
at com.capacitorjs.plugins.geolocation.GeolocationPlugin.handleOnResume(GeolocationPlugin.java:49)
at com.getcapacitor.Bridge.onResume(Bridge.java:1254)
at com.getcapacitor.BridgeActivity.onResume(BridgeActivity.java:86)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1364)
at android.app.Activity.performResume(Activity.java:7490)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4256)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4328)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2047)
at android.os.Handler.dispatchMessage(Handler.java:108)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7529)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
java.lang.RuntimeException: Unable to resume activity {ch.tpg.boldor/ch.tpg.boldor.MainActivity}: java.util.ConcurrentModificationException
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4288)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4328)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2047)
at android.os.Handler.dispatchMessage(Handler.java:108)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7529)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
Exemple of scenario, it is always more or less same
We have lot of crash due to this error in production on our app.
Expected Behavior
The expected behavior is that the app should resume normally from the background without any crash or exception related to the Geolocation plugin.
Additional Context
This issue seems to occur due to modifications in the HashMap within the GeolocationPlugin while iterating over it. This problem surfaces specifically when handling the onResume lifecycle event in Android.
The scenario is simple : on Android app, pass app in background, wait (only some ms is enough) then put it back in foreground -> crash
The issue is really complicated to reproduce. To "force" it, modify java/com/capacitorjs/plugins/geolocation/GeolocationPlugin.java and update this code :
@Override
protected void handleOnResume() {
super.handleOnResume();
// This loop is to force crash when switch background/foreground more times
for (int i = 0; i < 5; i++) {
new Thread(() -> {
try {
Thread.sleep(10); // Réduire le délai
if (!watchingCalls.isEmpty()) {
watchingCalls.remove(watchingCalls.keySet().iterator().next());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
for (PluginCall call : watchingCalls.values()) {
startWatch(call);
}
}
And I reproduce it more easily on physical device (on virtual too, but it is less frequent)
We have tried a fix with our team but we don't know if it is correct without knowing all context of Geolocation / Capacitor code :
@Override
protected void handleOnResume() {
super.handleOnResume();
List<PluginCall> watchingCallsValues = new ArrayList<PluginCall>(watchingCalls.values());
for (PluginCall call : watchingCallsValues) {
startWatch(call);
}
}
We are experiencing errors on iOS in production for many clients. I don't know if it is due to the plugin itself or something related to our usage of it.
Bug Report
Plugin(s)
Capacitor Version
Platform(s)
Current Behavior
When the application, which uses the Capacitor Geolocation plugin, is put into the background for a few minutes and then brought back to the foreground, the app crashes with a
java.util.ConcurrentModificationException
. This exception occurs in theGeolocationPlugin.handleOnResume
method, as detailed in the stack trace provided.Exemple of scenario, it is always more or less same
We have lot of crash due to this error in production on our app.
Expected Behavior
The expected behavior is that the app should resume normally from the background without any crash or exception related to the Geolocation plugin.
Additional Context
This issue seems to occur due to modifications in the
HashMap
within theGeolocationPlugin
while iterating over it. This problem surfaces specifically when handling theonResume
lifecycle event in Android.To reproduce
https://github.com/neogenz/capacitor-geolocation-sample
The scenario is simple : on Android app, pass app in background, wait (only some ms is enough) then put it back in foreground -> crash
The issue is really complicated to reproduce. To "force" it, modify
java/com/capacitorjs/plugins/geolocation/GeolocationPlugin.java
and update this code :And I reproduce it more easily on physical device (on virtual too, but it is less frequent)
We have tried a fix with our team but we don't know if it is correct without knowing all context of Geolocation / Capacitor code :