1

Nothing I've tried seems to solve my problem.

I have three buttons with with onClick behavior. Each of these buttons calls the same method launchActivity but with different parameters. launchActivity does some IO with the variables received from the onClick methods and then returns an intent. I would like to be able to implement a RxKotlin/Java Flowable to handle backpressure collectively across the three onClick methods so that I can implement BackpressureStrategy.DROP. So if onClick1 was initiated onClick2 would be dropped if initated while launchActivity was still processing onClick1 on the io() thread.

class ActivityLauncher {
  fun onClick1() {
    val intent = launchActivity(inFile1, outFile1)
    startActivity(intent)
  }

  fun onClick2() {
    val intent = launchActivity(inFile2, outFile2)
    startActivity(intent)
  }

  fun onClick3() {
    val intent = launchActivity(inFile3, outFile3)
    startActivity(intent)
  }

  fun launchActivity(in: File, out: File): Intent {
    // do IO with in and out files and create an intent
    return intent
  }
}

If I was to implement this as say a Single, I'd implement the onClick methods somewhat like:

fun onClick() {
  Single.fromCallable(launchActivity(inFile, outFile)
      .observeOn(scheduler.io())
      .subscribeOn(scheduler.ui())
      .subscribe { i -> startActivity(i) }
}

But I can't figure out how to call launchActivity from a shared Flowable that is accessible to all three onClick methods while still allowing them to pass in their unique inFile and outFile variables and enforcing backpressure.

The basic criteria is:

  • Ensure launchActivity is run on the io() thread
  • Pass the unique arguments from each of the onClick methods to launchActivity each time onClick[#] is run.
  • BackpressureStrategy.DROP is used to ensure only the first click in a series is processed in launchActivity
  • The resulting intent from launchActivity is passed to startActivity

How do I implement a Flowable to allow this behavior?

halfer
  • 19,824
  • 17
  • 99
  • 186
Dan 0
  • 914
  • 7
  • 15

1 Answers1

0

This doesn't really need to be done in a reactive way, seems like you're using it because of the convenience of threading - nothing wrong with that, however it brings complications when you try and model your situation using Rx.

Single is the correct operator to use - you only want 1 emission (BackpressureStrategy.DROP in a Flowable will still emit items of downstream if they can keep up). You just need to make your buttons isClickable = false at the start of your onClick(), and set then back to isClickable = true - something like :

Single.fromCallable { launchActivity(inFile, outFile) }
       .doOnSubscribe { disableButtonsFunction() }
       .subscribeOn(Schedulers.io())
       .observeOn(AndroidSchedulers.mainThread())
       .doFinally { enableButtonsFucntion() }
       .subscribe { i -> startActivity(i) }
Mark
  • 9,604
  • 5
  • 36
  • 64