Search code examples
androidmultithreadingrx-javarx-androidrxandroidble

How to make Android activity wait for completion of async process


Using RxAndroidBle for Bluetooth LE connections. It works to scan and identify devices with a given Service UUID (and add them to a Vector). But when I add a spinlock (actually an AtomicBoolean) in a while loop to detect when the scan is finished, it no longer seems to find the devices.

public void scanForScopes() {
    Log.d( LOG_TAG, "Entered scanForScopes()" );
    rxBleDeviceVector.clear( );
    asDeviceVector.clear( );
    // since we added time and device count limits, we know this Observable will not run forever
    scanSubscriber = new AsScanSubscriber<>( ); 
    scanSubscription = asBleClient
            .scanBleDevices( asServiceIdArray )
            .subscribeOn( Schedulers.io() )
            .observeOn( AndroidSchedulers.mainThread( ) )
            .take( MAX_SCOPES )
            .take( SCAN_TIME, TimeUnit.SECONDS )
            .doOnNext( this::addRxBleScanResult ) // works
            .doOnCompleted( () -> Log.d( LOG_TAG, "Scan for scope devices has completed" ) ) // doesn't seem to be called
            .subscribe( scanSubscriber ); // calls scanSubscriber.onStart() (which sets nowScanning true)

I suspect that a couple of things may be going on:

  1. The main UI thread has forged ahead and tried to display an empty vector of discovered devices. If that's the case, how can I make it wait for the device scan to complete without bogging down the system? I think the RxJava platform eliminates the AsyncTask option.
  2. The while() loop that tests for scan completion may be consuming too many CPU cycles, preventing the scan from succeeding. How can I fix this?

Solution

  • Solution to the problem was to avoid it, by using scanSubscriber's onCompleted() callback to continue the program's flow.