0

I am attempting to find a way to make one thread run for 2 seconds, and another run for 3 seconds. I am using the below runnables:

    private Runnable setLocation, checkWriteAttempt;

{
    setLocation = new Runnable() {
        @Override
        public void run() {
            // Get Location
            String location = FM.getLocation(SingletonSelectedMAC.getMAC());
            Log.e("Lockdown Pin", "Room Number = " + location);
            mConfirm.setEnabled(false);
            mCancel.setEnabled(false);
        }
    };

    checkWriteAttempt = new Runnable(){
        @Override
        public void run(){

            if(SingletonWriteData.getWasDataWritten()){
                startAlertActivity();
            }
            else{
                restartActivity();
            }

        }
    };
}

To start the threads, I am calling the method "attemptToWriteData" below.

My initial attempt was to use handlers that would use postDelayed to run a thread for a set amount of time. However, both runnables "setLocation" and "checkWriteAttempt" would run at the same time, which does not work for my program. Other than that, the new activity would start and work fine.

Later, I tried using the ScheduledExecutor. However, using this method, my activity will not change on my android device, and I receive no Log.e output from the runnables when they execute. The runnables are being called for sure because they are sending data to my bluetooth devices (lights). See below:

    public void attemptToWriteData(){
        scheduledExecutor.scheduleWithFixedDelay(setLocation, 0, 2, TimeUnit.SECONDS);
        scheduledExecutor.scheduleWithFixedDelay(checkWriteAttempt, 2, 3, TimeUnit.SECONDS);

        scheduledExecutor.shutdown();

        /*
        mHandler.postDelayed(setLocation, 2000);
        mHandler2.postDelayed(checkWriteAttempt, 3000);
        */
    }

Both threads require time to process background information from bluetooth devices (I have omitted this portion from the runnables as it is work related).

Thank you in advance for your advice!

1 Answers1

0

In order to run one thread for 2 seconds and other for 3 you would need an ability to suspend your threads, so the work would have to be subdivided into parts so that threads can pick-up from where they left off.

Running tasks each every fixed number of seconds is easier. Your approach with ScheduledExecutor probably does not work because you try to update UI not on the main android thread.

Try following solution using RxAndroid library. You will have to convert your Runnable to Callable so they return result of the computation that can be then used to update UI:

Observable<Integer> o = Observable.merge(
    Observable.interval(2, TimeUnit.SECONDS).map(t -> setLocation),
    Observable.interval(3, TimeUnit.SECONDS).map(t -> checkWriteAttempt)
)
.map(c -> c.call())
.subscribeOn(Schedulers.single())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(computationResult -> /*update UI here*/);

This code will make sure that callables do not run concurrently and that UI updates are run on the main thread.

hgrey
  • 3,033
  • 17
  • 21