I have reposted my question from Android Enthusiasts here, as this is more of a programming question, and it was recommended.
Anyway. Here it is:
I am making an app, that changes the build.prop of key values for a ROM. However, Android often gives me an ANR warning, as I am doing all the work on the UI thread. On the Android documentation, it tells me that I should use worker threads, and not do any work in the UI thread. But, I am building this system app to go with a ROM for a single core device.
Why would I want to use worker threads, as isn't this less efficient? As, Android has to halt the UI thread, load the worker thread, and when the UI is used again, halt the worker thread and load the UI thread again. Isn't this less efficient?
So, Should I use worker threads (Which slows the UI thread down anyway) or just do all of my work on the UI thread *Even if the application UI is really slow)?
If your users were robots, your logic would make perfect sense. No context switching equals (very slightly) less overall computation time. You could benchmark it and see how much exactly.
However, in the present (and near future) your users will most likely be humans and with that you need to start thinking of psychology: A moving progress bar or responsiveness in general will give your users the impression that the the task is actually taking a shorter time than without any sort of feedback. The subjective speed is much higher with feedback.
There exist numerous papers on the subject of subjective speed, the first one I could find on the web has a nice comparison of progress bars in a video (basically, some bars seem to go faster than others, thus reducing the subjective overall wait time).
Use worker threads.
As you've said, doing everything on the UI thread locks your UI until the operation is completed. This means you can't update progress, can't handle input events (such as the user pressing a cancel button), etc.
Your concern about the speed of context switching is misplaced - this happens all the time anyway, as core system processes and other apps run in the background. Some quick Googling shows that context switching a thread within the same process is typically faster than a process-level context switch anyway. There is slightly more overhead introduced by creating the threads and then the subsequent context switches, but it's likely to be minute - especially if you only have the 1 thread doing the work. For the reasons I've listed above alone (UI updates and the ability to accept user input), take the few-millisecond overall performance hit.
Related
This question is different than what's being discussed about Main thread and UI thread in Android.
By mean of System thread - the thread which handles system UI like statusbar, notifications & other ongoing system processes, say thread which handles home-button-press, recents-menu etc...
By mean of Main thread - App's thread which handles UI (forked when process launched)
I believe it's saperate thread as busy main thread of app is not hanging your device and all other than app things work fine.
My doubt is only for the purpose:
If system can manage a separate thread for it self (to do UI work) than any process/app's-main thread; then why Apps can not have multiple threads who can handle UI (No matter how complex it's for devs!!)
Please provide references as well while pointing out answers on this.
By mean of System thread - the thread which handles system UI like statusbar, notifications & other ongoing system processes, say thread which handles home-button-press, recents-menu etc...
There may well be several threads involved in this.
I believe it's saperate thread as busy main thread of app is not hanging your device and all other than app things work fine.
More importantly, system UI is handled by separate OS processes, independent of the OS process for an app. As with most modern operating systems, in Android, a thread is owned by a process. Hence, by definition, separate processes have separate threads.
then why Apps can not have multiple threads who can handle UI (No matter how complex it's for devs!!)
That was an architectural decision, made close to 15 years ago, back when phone hardware was a lot more limited than it is today. Having a single "magic thread" is a common practice in constrained environments, as it avoids the overhead of constant checking for locks and other approaches to ensure thread-safety of data structures. While Google has done some things to try to improve on this (e.g., added a separate rendering thread), the core architectural limit remains, for backwards compatibility with older apps.
Also note that a fair amount of work is going into Jetpack Compose to try to allow for multi-threaded composables. Basically, since we now have a lot better hardware, Google is handling low-level synchronization for us in Compose, so composables can perhaps run on several threads without issue.
I am a mediocore android developer for years. I like android but there's a big problem; frame drops. Even the most powerful ones can stutter so frequently while IOS devices can run at constant 60fps. I just can't understand why. I want to know it. So first thing i did was watching an I/O presentation about performance. And i didn't really understand one thing. Why can't ui and render thread run at the same time ? Yeah i know the basics like render thread can't know what to render while ui thread is doing it's thing but why can't render thread render the frame before? You can see the video here:
https://youtu.be/9HtTL_RO2wI?t=491
And here's a diagram what am i asking for:
You get the idea. I don't know about low level things about android, can anyone explain this like i'm five.
Your process' main thread is responsible for the rendering of the frames that will be presented to the user, so you should keep the code running there as fast and light as possible. If you have to do some heavy processing or access any IO (network, sdcard, etc) that may impact on the fluidity of the application since the thread may be waiting for a response.
As a good practice you should start that IO access/heavy processing on another thread to run in background and let the system decide the priority to run it, if necessary is recommended to present some feedback to the user like a ProgressBar or something to indicate that something is being processed.
Also, the Render Thread need to know what to render before it does it, so the UI Thread have to process which information the app would like to present to the user.
As #JonGoodwin points out, they both run in parallel, but usually in two cores of the same processor, as nowadays phones have at least two cores. Both threads are run in CPU, where RenderThread sends rendering commands to the GPU. Notice that this is true since API 21 (RenderThread is what enables things like ripple effect).
The problem, though, is what #LucianoFerruzzi points out: usually poor code that does too many things in the UI thread (RenderThread is not accessible, at least not with standard mechanisms).
Also, see the following episode of Android Developers Backstage: Episode 74: Graphics
I am porting over an application that has been written already in C++ to run on Linux that now needs to run on an Android device. It is a GPU intensive app that makes OpenCL calls, running a set of tests. These could take up to several hours or days to finish running.
I have a Java Activity that reads in some basic input, then passes that to the JNI.
It runs fine for shorter operations, but beyond several seconds it will pause; I can unpause it and it will continue to run, but then it hangs heavily every hundred or so operations (taking a minute for what should take less than a second).
Is there something I am lacking in Android knowledge, some critical fallacy I've overlooked that might be causing this? Would it make more sense to move all of the code to a NativeActivity? Or do I just need to make calls back to Java to display something every so often to prevent the OS from shutting me down?
Thanks to any who have the patience to answer my questions
On Android, it is a strong rule that no CPU intensive long operations should run on the UI thread. Neither switching to NativeActivity nor callbacks to display something will not help, but if you run the tests on a worker thread, I might be wise to update the screen from time to time for the user to keep track of the overall progress.
Heavy tasks in Android should be executed in background threads. Heavy tasks are:
database tasks
work with images, audio, video
fetching and parsing internet data
some extensive calculations (very rare in most apps)
What else can be considered as a heavy task and should be executed in background thread?
I am getting an ANR error and I need to know which tasks Android interprets as heavy tasks.
The system doesn't throw up the ANR because it notices that you're doing something that it categorizes as "heavy"; it produces the ANR because the user interface is unresponsive. Using debug statements (i.e., Log.d()) you need to track the progress of your app and figure out what it's doing (or trying to do) when you get your error. For example, an infinite loop on the UI thread would produce an ANR, but there's (provably) no way to categorize any arbitrary loop as infinite or not.
What else can be considered as a heavy task and should be executed in background thread?
If it takes more than couple of milliseconds, it should be executed in a background thread.
Courtesy of Project Butter in Android 4.1, the Android UI now updates at 60fps, meaning that there is ~16ms to do everything that is needed to render a frame. The OS needs some of that time to do the actual rendering. If you take more than a few milliseconds, you may skip a frame, causing "janky" behavior. Even on earlier versions of Android, the effect can be seen -- it's just going to be more jarring on Jelly Bean, because everything else is smoother.
Just wondering if threading with one processor improves things for me.
I am building an application that performs data intensive calculations (fft on pcm data) while a UI is running and needs to run smoothly.
I have been looking at AsyncTask but was thinking:
If I have a single core processor (600 MHz ARM 11 processor) running on my Optimus One, will threading make a difference? I thought for threads to run independantly you would need multiple processors? Or have I gone wrong somewhere?
In order to guarantee responsiveness, it is imperative to leave the main or UI thread to do the UI things. This excludes intensive drawing or 3d rendering in games. When you start to do computationally intensive things in your main thread, the user will see lag. A classic example:
on a button click, sleep(1000). Compare this with, on a button click, start an AsyncTask that sleeps(1000).
An asynctask (and other threading) allows the app to process the calculations and UI interactions "simulataneously".
As far as how concurrency works, context switching is the name of the game (as Dan posts).
Multithreading on a single core cpu will not increase your performance. In fact, the overhead associated with the context switching will actually decrease your performance. HOWEVER, who cares how fast your app is working, when the user gets frustrated with the UI and just closes the app?
Asynctask is the way to go, for sure.
Take a look at the Dev Guide article Designing for Responsiveness.
Android uses the Linux kernel and other specialized software to create the Android Operating System. It uses several processes and each process has at least one thread. Multi-threading on a single (and mutiple) processor hardware platform is accomplished by context switching. This gives the illusion of running more than one thread per processor at a time.