ANDROID DEVELOPMENT
“Skipped 611 frames! The application maybe doing too much work on its main thread.”
As a matter of fact, we all have come across this message at some point during Android development.
But, have you ever wondered why we used to get this kind of message when we were trying to execute network calls from the UI thread (Main thread)?
Yeah, we all know that, If the app is doing too much work on the UI thread, the app will become less responsive, i.e. it will freeze — producing the ANR (Application Not Responding) dialog. 😛
Cool. But, do we know the internals of it?
What exactly happens under the hood and the app becomes unusable?
What about the number 611 frames
(or any other number for that matter)?
I mean, this arbitrary number “611” just popped up, out of nowhere!!
WHY? 🤔
Honestly, I was not aware of it! 😕
So, without wasting any time, let’s dig deeper into it:
Typically, Android apps should render 60 frames per second on device screen (yes, in today’s world the screen refresh rate can go upto 90Hz or 120Hz but let’s just stick with 60Hz for this example).
Now, if we do the math, we will see:
Each new frame should be rendered in ~16.67 milliseconds.
We know that, the UI related stuffs happen in the UI thread. Starting from UI manipulation (e.g. button click, swipe, providing text input etc.) to rendering — all these things take place in the UI thread!
Thus, if we consume too much time on the UI Thread, then this thread might not be able to provide new frames every 16 milliseconds. And this will end up showing the ANR dialog.
Let’s try to understand this with an example:
Suppose, we are trying to execute network operations (for maybe 10 seconds) on the UI thread (considering the screen refresh rate is 60Hz, i.e. 60 fps).
So, the calculation would look something like:
60 frames should be rendered in 1s.1 frame should be rendered in (1/60)s.This, in turn means:
611 frames should have been rendered in (611/60)s = 10.183s ≈ 10s.
But, these 611 frames could not be rendered as the UI thread was blocked for 10 seconds due to network operations → resulting in the infamous ANR dialog:
“Skipped 611 frames! The application maybe doing too much work on its main thread.”
What’s the solution then?
Well, the answer is simple!
“Execute all the long-running tasks in a background (or worker) thread!”
This can be achieved in several ways:
- Using bare Threads
(tip: Don’t use it. Use RxJava or Coroutines instead) - RxJava Schedulers
(e.g. Schedulers.io() / Schedulers.computation() — based on the use-case) - Coroutines Dispatchers
(e.g. Dispatchers.IO / Dispatcher.Default — based on the use-case)
Thanks for reading the article.
Please share and clap 👏 if you have found this useful.
You can also checkout my other articles here.
Happy Coding!
Cheers! 🙂