-1

I am developing an Android app which uses the accessibility service. It has some processing which needs to be executed immediately. But this process freezes the main thread and leads to the app not responding. So, I used kotlin coroutines to do the heavy processing in the background threads. But the problem is that , while it does not freeze the UI, it takes some time to complete. It is not immediate.

How can I do the processing immediately without freezing the UI ?

My code :

class CustomAccessibilityService : AccessibilityService() {

private val accessibilityScope = CoroutineScope(IO)

    val accessibilityScopeExceptionhandler = CoroutineExceptionHandler {
            context, exception -> Log.wtf(this::class.java.simpleName,"Caught exception. ${exception.message}")
    }

override fun onAccessibilityEvent(event: AccessibilityEvent?) {

accessibilityScope.launch(accessibilityScopeExceptionhandler) {

// Some heavy processing.

withContext(Main){

// Take UI actions 

    }

  }

 }

}

Everytime an event happens, I get multiple onAccessibilityEvent() callbacks and a coroutine launch happens. So, it takes time to complete.I want to complete the heavy processing immediately.

Are coroutines the best option to achieve my goal ?

  • What do you mean by saying that processing should be completed immediately? You probably understand that processing and especially some heavy one requires some time to complete. Do you need to process multiple events sequentially, so not in parallel? Or maybe you need to do something after the processing finishes? – broot Dec 24 '21 at 09:15
  • The processing completes so fast when it is done on the main thread but it freezes the UI. When I moved the processing to coroutines, it is slower. Can I achieve the same processing speed without blocking the UI ? – Binish Mathew Dec 24 '21 at 10:32
  • Honestly, it's hard to believe processing is faster on UI thread. There shouldn't be a difference, so I guess there is something else going on. How do you observe the difference? And how big is it? – broot Dec 24 '21 at 10:45
  • 1
    For example, if you update UI, then start processing and then update UI again then by blocking UI thread you will get an impression that processing is immediate. This is because UI is frozen, so you will see first update after the processing finishes, not before. But this is just a blind guess on what might happen here – broot Dec 24 '21 at 10:48

1 Answers1

2

Speed of execution depends on your device's computing capabilities, you can't expect results to be quicker than that.

As per my experience, using Dispatchers.Default is the fastest way to get this done. Few other pointers to note —

  1. Check whether your heavy computation could be parallelized by launching multiple coroutines operating on unique data (SIMD).
  2. Check whether you could take advantage of the device's GPU capabilities using some Rederscript alternatives mentioned here
  3. You may schedule an Expedited Work from the WorkManager if you want your operation to continue when the app is not in the foreground, but this again adds the complexity of WorkManager scheduling and you won't find it quicker than using Dispatchers.Default explicitly.
Kshitij Patil
  • 132
  • 1
  • 9