I read on post that Coroutine isn't a good practice for using on splash screen and Executors is the best for that because Coroutine takes a time to start more than Executors, but I didn't find an example of implementing that, is the Executors is the normal java Executor class which used to manage thread pool?
-
1"I read on post that Coroutine isn't a good practice for using on splash screen and Executors is the best for that because Coroutine takes a time to start more than Executors" -- that does not make a lot of sense. – CommonsWare May 06 '21 at 12:58
-
1https://www.facebook.com/codingwithnerds/posts/506630070728865 here the post I mean – May 06 '21 at 13:03
-
How about Handler? – Sajad Hosseini May 06 '21 at 13:13
-
@SajadHosseini I can use it but I wonder what is Executors? – May 06 '21 at 13:14
-
1checkout this post and related comments https://www.reddit.com/r/androiddev/comments/kt3d7o/android_startup_tip_dont_use_kotlin_coroutines/ – William Reed May 06 '21 at 14:15
2 Answers
First, for splash best performance you must read the link mentioned in comments by William Reed here and here and also this other link here
and when you read the articles focus on these words
The measurements were made on a debuggable app differ surprisingly from production performance
As pointed out by Jake Wharton, the difference is partly due to ExecutorService being preloaded by the Zygote, a special part of the Android framework that shares code between processes. Other concurrency frameworks which, like coroutines, aren’t preloaded, will also have a comparatively high initialization cost. That said, coroutines have a lot of advantages over ExecutorService. They’ve got scopes, suspending functions, they’re much more lightweight than threads, etc. The general recommendation to use them in Android applications is sound, but their impressive feature set has an initialization cost at the moment. Perhaps the Kotlin and Android teams will be able to optimize this in the future. Until then, best to avoid using coroutines in your Application class, or in your main Activity, if startup time is a primary concern.
Second, for your other part of the question I think that is the Executor you asked about
And here how to use it
1 - To execute code in the main thread
// Create an executor that executes tasks in the main thread.
val mainExecutor = ContextCompat.getMainExecutor(this)
// Execute a task in the main thread
mainExecutor.execute {
// You code logic goes here.
}
2 - To execute code in a background thread
// Create an executor that executes tasks in a background thread.
val backgroundExecutor: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
// Execute a task in the background thread.
backgroundExecutor.execute {
// Your code logic goes here.
}
// Execute a task in the background thread after 3 seconds.
backgroundExecutor.schedule({
// Your code logic goes here
}, 3, TimeUnit.SECONDS)
Remember to shut down the executor after using.
backgroundExecutor.shutdown(); // or backgroundExecutor.shutdownNow();
3 - To execute code in a background thread and update UI on the main thread.
// Create an executor that executes tasks in the main thread.
val mainExecutor: Executor = ContextCompat.getMainExecutor(this)
// Create an executor that executes tasks in a background thread.
val backgroundExecutor = Executors.newSingleThreadScheduledExecutor()
// Execute a task in the background thread.
backgroundExecutor.execute {
// Your code logic goes here.
// Update UI on the main thread
mainExecutor.execute {
// You code logic goes here.
}
}
what is the best for performance on Debug (Production May vary as mentioned before)?- Executor, and Coroutine takes much time based on trying both of them with this function
fun TestPerformance(){
val startTime = System.nanoTime()
// DEBUG in handler 3002952707
Handler(Looper.getMainLooper()).postDelayed({
val endTime = System.nanoTime()
println("DEBUG in handler ${endTime-startTime}")
}, 3000)
// DEBUG in backgroundExecutor 3001161822
val backgroundExecutor: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
backgroundExecutor.schedule({
val endTime = System.nanoTime()
println("DEBUG in backgroundExecutor ${endTime-startTime}")
}, 3, TimeUnit.SECONDS)
// DEBUG in GlobalScope 3046312603
GlobalScope.launch {
delay(3000)
val endTime = System.nanoTime()
println("DEBUG in GlobalScope ${endTime-startTime}")
}
}
As you can see I add another way to the comparison with handler too, and look at the comments in the code, both handler and Executor faster than Coroutine and sometimes handler wins and sometimes Executor wins, both of them gives the same performance.
and if you want more examples for how to use handler check this answer it's a great help and I used it in my answer.

- 463
- 2
- 11
- 29
once you have an Executor instance, you can submit multiple tasks to it, and have them executed one after another. You can't do that simply with a raw Thread.
Creates an Executor that uses a single worker thread operating off an unbounded queue. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.) Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time.
Executors.newSingleThreadExecutor().execute {
// todo.
}

- 476
- 3
- 9