Skip to content

java.util.ConcurrentModificationException: Unable to create service org.altbeacon.beacon.service.BeaconService #1243

Description

@rubnov

I am using Altbeacon version 2.21.1 and seeing this crash in my Android app:

Fatal Exception: java.lang.RuntimeException: Unable to create service org.altbeacon.beacon.service.BeaconService: java.util.ConcurrentModificationException
       at android.app.ActivityThread.handleCreateService(ActivityThread.java:3768)
       at android.app.ActivityThread.access$1400(ActivityThread.java:237)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1801)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:214)
       at android.app.ActivityThread.main(ActivityThread.java:7050)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)

Caused by java.util.ConcurrentModificationException:
       at java.util.ArrayList$Itr.next(ArrayList.java:860)
       at java.util.AbstractCollection.addAll(AbstractCollection.java:343)
       at org.altbeacon.beacon.service.ScanHelper.reloadParsers(ScanHelper.java:179)
       at org.altbeacon.beacon.service.BeaconService.onCreate(BeaconService.java:243)
       at android.app.ActivityThread.handleCreateService(ActivityThread.java:3756)
       at android.app.ActivityThread.access$1400(ActivityThread.java:237)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1801)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:214)
       at android.app.ActivityThread.main(ActivityThread.java:7050)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)

Looking at the full stack trace, I can see this stack on another thread:

pool-25-thread-1:
       at android.os.BinderProxy.transactNative(Binder.java)
       at android.os.BinderProxy.transact(Binder.java:1145)
       at android.app.IActivityManager$Stub$Proxy.bindService(IActivityManager.java:4223)
       at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1761)
       at android.app.ContextImpl.bindService(ContextImpl.java:1701)
       at android.content.ContextWrapper.bindService(ContextWrapper.java:711)
       at org.altbeacon.beacon.BeaconManager$4.bindService(BeaconManager.java:2158)
       at org.altbeacon.beacon.BeaconManager.bindInternal(BeaconManager.java:622)
       at org.altbeacon.beacon.BeaconManager.autoBind(BeaconManager.java:2162)
       at org.altbeacon.beacon.BeaconManager.startMonitoring(BeaconManager.java:1415)
       at nl.hgrams.passenger.services.PSBluetoothService.addRegion(PSBluetoothService.java:1574)
       at nl.hgrams.passenger.services.PSBluetoothService.monitorAllBeaconRegions(PSBluetoothService.java:1764)
       at nl.hgrams.passenger.services.PSBluetoothService.initBeaconManager(PSBluetoothService.java:1277)
       at nl.hgrams.passenger.services.PSBluetoothService.lambda$startBeaconManager$11(PSBluetoothService.java:1254)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
       at java.lang.Thread.run(Thread.java:764)

This looks similar to this closed issue: #929

The issue is inconsistent and only occurred on a handful of devices, running Android 9-13.

My understanding of what's happening:

  • My app launches and initializes BeaconManager.
  • During initialization, the app starts monitoring a region (pool-25-thread-1). BeaconManager attempts to bind to BeaconService.
  • However, at the same time BeaconService is being created. This results in the exception above.

Am I using the library incorrectly? Should I check BeaconService prior to calling startMonitoring?

Here is the relevant app code:

    /**
     * Initialize beacon manager to monitor beacon regions.
     */
    public void startBeaconManager() {
        BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        int result = BeaconTransmitter.checkTransmissionSupported(context);
        if (mBluetoothAdapter != null && result != BeaconTransmitter.NOT_SUPPORTED_BLE &&
                result != BeaconTransmitter.NOT_SUPPORTED_MIN_SDK) {
            if (Utils.hasPermissionBluetooth(context)) {
                ExecutorService executor = Executors.newSingleThreadExecutor();
                executor.execute(() -> initBeaconManager(context));
            }
        }
    }

    public void initBeaconManager(Context context) {
        if (beaconManager == null) {
            beaconManager = BeaconManager.getInstanceForApplication(context);
        }

            enableForegroundScanning();
            monitorAllBeaconRegions();
       ...
    }

    private void monitorAllBeaconRegions() {
        if (mIsAddingRegions) {
            return;
        }
        mIsAddingRegions = true;
        Realm realm = RealmManager.getInstance();
        BeaconSetting beaconSetting = realm.where(BeaconSetting.class).findFirst();
        if (beaconSetting != null) {
            addRegion(beaconSetting.getDefault_beacon_uuid()); 
        }
        ...
    }

    public void addRegion(String uuid) {
        if (uuid == null) { return; }
        if (beaconManager == null) { return; }
        Region region = new Region(uuid, Identifier.parse(uuid), null, null);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
                !PSLocationService.userHasGrantedFineLocationPermission())
        {
            return;
        }
        beaconManager.startMonitoring(region);
    }

    public void enableForegroundScanning() {
        if (beaconManager != null) {
            if (beaconManager.getForegroundServiceNotification() != null) {
                return;
            } else if (beaconManager.isAnyConsumerBound()) {
                return;
            }
        }
        beaconManager.enableForegroundServiceScanning(
                NotificationCreator.getForegroundServiceNotification(PSApplicationClass.getInstance()),
                NotificationCreator.NOTIFICATION_ID_FOREGROUND_SERVICE);
        beaconManager.setForegroundBetweenScanPeriod(10000);
        beaconManager.setBackgroundBetweenScanPeriod(60000);
        beaconManager.setForegroundScanPeriod(5000);
        beaconManager.setBackgroundScanPeriod(4000);
    }

Thank you for your guidance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions