I am still confused at threads. Still I could see some answers which points to threads, UI thread, background thread, main thread etc. (mostly on AsyncTasks and updating UI from background threads etc.)
Could anyone give me a complete explanation around these or some links at least?
It would be great if the answer covers the following cases:
Which are all the threads that's involved:
When I am running an activity (setting the content view, attaching some buttons, some dialog messages)
An activity with AsyncTask
A Background Service
A HTTP call
UI thread (main thread) - it is crucial to instantiate (add) all UI elements on this thread, that is why it has a nickname UIThread
AsyncTask - has methods doInBackground, onPostExecute, etc. Sort of its own lifecycle
Background Service (service) A service runs by default in the same process as the application. in its own thread. (as pointed out by #MisterSmith) A service runs by default in the same process as the application. in its own thread. Therefore you need to use asynchronous processing in the service to perform resource intensive tasks in the background. Services which run in the process of the application are sometimes called local services.
Thought you can specify to run a Service in its own process:
Running a service in its own process will not block the application in case the service performs long running operations in its main thread. But as the services runs in its own process you need to use some interprocess communication (IPC) to communicate to your service from other parts.
HTTP call executed using HttpClient (from docs:
Thread safety of HTTP clients depends on the implementation and
configuration of the specific client.
), has to be executed on non-UI thread by using new Thread(new Runnable(...)).start();, otherwise you will get NetworkOnMainThreadException thanks to #vikram. But it seems that HttpClient.execute() method is executed in a thread, that is why it requires a handler as one of the parameters in order to pass the result to the corresponding handler (handler runs on UI thread and can update widgets (UI elements) as it is needed)
Extra:
To force something to be executed on your main thread use yourContextInstance.runOnUiThread(new Runnable(....));
In order to determine if current thread is UI(main) thread:
Looper.getMainLooper().getThread() == Thread.currentThread();
Interesting question about threads in a service:
Does a runnable in a service run on the UI thread
Why UI thread is responsible for all this?
Because UI thread is in charge of dispatching the events to the
appropriate widgets (UI elements), which includes the drawing events
Sources: this that and a little bit of that and some of that
When I am running an activity ( seting a content view , attaching some buttons, some dialog messages )
Usually only one thread (the main one, sometimes incorrectly called UI thread).
Activity - with async task
Again, by default only one (the main one). Menus and button handlers also run in the main thread. AsyncTask is a different story. It creates a worker thread (btw you should be careful not to leak it when exiting the activity).
Background Service
A service runs by default in the main thread. So do broadcast receivers. And this is why the main thread is not (only) the UI thread. Some types of services (like the popular IntentService) spawn a worker thread though.
An http Call
Is a synchronous operation, so it blocks until it completes (and this is why you should never perfom one in the main thread).
Technically speaking an application can have as many threads as it wants, they are arbitrarily created by the programmer.
However, the standard android application by default has one thread. That is the main thread, and is often referred to as the UI thread (as it is the only thread with access to the UI). By default everything happens in the main thread.
If you run an async task, different parts run in different threads, here's a basic breakdown:
onPreExecute() runs in the UI thread and is first called when you execute an async task.
doInBackground() runs in a newly spawned thread separate from the main/UI thread.
onPostExecute() runs in the UI thread after the background task returns.
A background service runs entirely separately from the application, it can run indefinitely even if the original application is destroyed.
An http call happens on whatever thread you call it on, but as a requirement of newer android API's you can no longer do any network activity from the main/UI thread. (This will actually cause an exception and terminate your application) This is to prevent slow network calls from blocking the main thread and therefore creating a choppy user experience.
Which are all the threads that's involved:
When I am running an activity (setting the content view, attaching some buttons, some dialog messages)
UI Thread or Main Thread is involved here.
An activity with AsyncTask
Both UI Thread and WorkerThread is involved.
AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
The 4 steps
When an asynchronous task is executed, the task goes through 4 steps:
onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). This method is used to display any form of progress in the user interface while the background computation is still executing.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
A Background Service
The IntentService class provides a straightforward structure for running an operation on a single background thread. This allows it to handle long-running operations without affecting your user interface's responsivenes
A HTTP call
NetwokrkOperation can't be executed from UI Thread ( or MainThread). So use alternatives like AsyncTask or HandlerThread
Related posts:
Handler vs AsyncTask vs Thread
Why use HandlerThread in Android
Asynctask vs Thread vs Services vs Loader
Related
For example, there are a lot of tasks are posted to UI thread as follows.
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Some logic to display/update something in UI
}
}, 5000);
What happens to these tasks when the android application went to the background?
Will these tasks be processed even in the background? Will the complete UI thread be suspended in the background? Or? All the tasks posted to UI thread are suspended?
What happens to UI thread when there are no tasks posted to it after the activity is completely loaded? Will it be suspended, if there are no tasks are in the Looper?
Thanks in advance.
Let's get's dirty with few terms first.
Handler:
A Handler allows communicating back with UI thread from other
background thread. This is useful in android as android doesn’t allow
other threads to communicate directly with UI thread.
In technical terms, it is a way to post Messages or runnable to your associated thread message queue.
so in total there are two task performed by handler
to schedule messages and runnables to be executed as some point in the future; and
to enqueue an action to be performed on a different thread than your own.
so how to schedule one
post(Runnable),
postAtTime(Runnable, long),
postDelayed(Runnable, Object, long),
sendEmptyMessage(int),
sendMessage(Message),
sendMessageAtTime(Message, long),
sendMessageDelayed(Message, long).
Looper:
Whatever I mentioned earlier is supported by Looper It has a loop()
method which keeps running and listening for the new messages, main thread has one running all the time so you can receive messages from another thread to this thread, if you are creating your own thread and want to listen then don't forget to call prepare() in the thread that is to run the loop.
A simple example
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
so now to answer your questions:
1: Things(Threads and so Looper and Handler) keep running until it gets finished by the user or killed by the system.
2: A looper has a loop() method that will process each message in the queue, and block when the queue is empty.
3: In case of updating the UI from background thread make sure app is in the foreground or terminate the background thread in onDestroy() you can quit the looper processing messages using handler.getLooper().quitSafely() or handler.looper.quit() if the handler is attached to the main thread.
It's recommended in case of orientation change or other configuration changes make sure to terminate the background thread.
There are many answers concerning the case. I will try to answer exactly to the questions.
What happens to these tasks when android application gone to background?
Nothing is interrupted. Handler will post a Message on MessageQueue on the specified time (unless the hosting process is killed).
Will these tasks are processed even in the background?
From the standpoint of Handler: it doesn't know whether the app is in foreground or background. All it knows, is that it should post a Message some time later.
Will the complete UI thread be suspended in background? Or? All the tasks posted to UI thread are suspended?
What happens to UI thread when there are no tasks posted to it after the activity is completely loaded? Will it be suspended, if there are no tasks are in the Looper?
UI thread won't be "suspended" in any case (unless the hosting process is killed). It's just that it will be idle as a result of MessageQueue being empty - thus no job is needed to be done.
As a side note, refrain from performing UI related actions when app goes to background, because the state of view hierarchy won't be saved correctly. Assume you have performed textView.setText("bob") at a time, when app is in background. Now, the state of this TextView won't be saved, because onSaveInstanceState() has already been executed and won't be executed again, thus if process of the app is killed and recreated (i.e. as a consequence of system resources shortage), then the activity will be restored with a state that it had possessed when onSaveInstanceState() was called. Now user won't see "bob".
You can cancel the scheduled event using Handler#removeCallbacks() API.
UI thread is also known as the Main thread, it's a thread launched by default when you open your application and where all your interactions happen unless you offload them to some other thread. It's not dependent on the visibility of the app, it's running as long as the app lives. It's not suspended by the system.
What happens to UI thread when there are no tasks posted to it after the activity is completely loaded? Will it be suspended, if there are no tasks are in the Looper?
Let's start with the Looper concept. It's very important for understanding how UI thread is working. Looper is a thing that loops in a given thread and handles incoming messages, when there are no tasks it's looping and waiting for new tasks, so, answering your last question, the thread will not be suspended. Looper is designed to keep the thread alive even when there are no tasks. UI thread in Android has it's own Looper by default.
What happens to these tasks when android application gone to background?
Will these tasks are processed even in the background? Will the complete UI thread be suspended in background? Or? All the tasks posted to UI thread are suspended?
Going to background does not change anything for the main thread. It's running until the application is killed. So your code scheduled on a handler will just run.
On a side note. The possible problem here is that while activity is in the background it can be killed by the system and you attempt to change UI of it will crash the app (there are a few similar scenarios), but it's not really related to the UI thread.
All in all, the UI thread is not suspended by the framework under any conditions. It just runs and processes everything you give it or waits until new tasks are given to it.
Here you can find the description of the main thread in the official docs.
This is a good SO thread about looper.
What happens to these tasks when android application gone to
background?
It will work as intended, No change in the behavior of UI Changes. Only thing is we are not able to see those changes.
Best Solution:
Update any view inside your handler when app is in background
eg: TextView and set some text in it, and get this TextView value once the application goes in the foreground.
Will these tasks are processed even in the background? Will the
complete UI thread be suspended in background? Or? All the tasks
posted to UI thread are suspended?
As I mentioned above this task will work as it is.
The application does not change UI thread when you move to the background, It will remain as it is.
What happens to UI thread when there are no tasks posted to it after
the activity is completely loaded? Will it be suspended, if there are
no tasks are in the Looper?
Putting it simply, there are Looper threads, for example, UI thread. Such thread has its own Looper, which runs a message loop for the thread. Once message queue is finished it will be finish itself.
UI thread will not be suspended at any cost by itself, Until and unless you write some code to change it :).
Nice to read:
Androids Handler.post, what happens exactly
What is the relationship between Looper, Handler and MessageQueue in Android?
So, I am working with some code that performs seemingly asynchronous tasks and uses the typical callback/listener model to receive callbacks.
My problem is that sometimes the callbacks never fire if I hold up the thread that called the operation.
Considering the following snippet of code:
doAsync(new Callback(){
// Callback here
});
The internals of doAsync() are using a handler and the main looper.
Considering I call this code from Thread A can somebody please outline the effects of blocking the Thread A right after this call.
Also, what are the effects of running the Handler on main looper and local looper will it determine the thread that the above callback is executed on? I ask this because if I block Thread A then the callback never executes.
calling in Async Task does not block the main thread...doInBackground method executes the operations in background thread...if you want to update the UI after your execution in background has completed you must override the onPostExecute() method....there are some other hooks for UI thread too like onProgressUpdate and OnCancelled in AsyncTask....please check the java doc of AsyncTask for details
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
This is a clarifying question regarding the AsyncTask class and a specific example of using the class to do a networking operation(grabbing data).
How is the onPostExecute method running synchronously after the doInBackground operation any different than having the main thread do all the work(onPostExecute and doInBackground)?
That main thread would do these operations sequentially, grabbing network data an then performing the work in onPostExecute.
From the docs:
When an application is launched, the system creates a thread of execution for the application, called "main." This thread is very important because it is in charge of dispatching events to the appropriate user interface widgets, including drawing events.
In other words, ALL UI-related tasks occur on the same thread, and it is called the main thread or UI thread.
When your app performs intensive work in response to user interaction, this single thread model can yield poor performance unless you implement your application properly. Specifically, if everything is happening in the UI thread, performing long operations such as network access or database queries will block the whole UI.
Simply put, when the UI has to wait for some I/O, data retrieval or data processing to complete before it can finish rendering the screen, your application "hangs" till that process is complete.
The user might then decide to quit your application and uninstall it if they are unhappy.
I think this is self-explanatory.
There are simply two rules to Android's single thread model:
Do not block the UI thread
Do not access the Android UI toolkit from outside the UI thread
Hence, everything not related to the UI MUST be done in a separate thread, and everything related to the UI MUST be done WITHOUT any kind of parallel processing.
So how do we perform parallel processing ? Android offers different kinds of parallel processing based on your needs:
1. Good old Java Threads
2. Handlers
3. Activity.runOnUiThread(Runnable)
4. View.post(Runnable)
5. View.postDelayed(Runnable, long)
6. AsyncTasks
7. IntentServices (Services DO NOT run on a separate thread).
On a side note, Android specifically enforces that all network operations be performed on a separate thread, else a NetworkOnMainThreadException is thrown.
Now coming back to your question :
My question is how is this difference form just running everything on the main thread? I know that onPostExecute has to wait for the xml do in background retrieve to finish which will still lock up the ui for the user?
What happens is that if the device has more than one core, UI rendering is done through one core (the main thread) while the doInBackground() method is executed on the other core (the AsyncTask thread), and the onPostExecute() method is called on the main thread only after doInBackground() has returned. This means that onPostExecute() is also waiting for the UI to finish rendering, as both UI rendering & onPostExecute() occur on the main thread.
Now if the device has only one core, everything will happen on a single core, but doInBackground() will be executed on a separate thread, and onPostExecute() will be called only after UI rendering is complete and doInBackground() has returned.
I hope this was helpful.
Further Reading:
1. Understanding AsyncTask – Once and Forever
2. Is Android’s AsyncTask executing tasks serially or concurrently?
It's not about efficiency: network I/O is explicitly prohibited in the main thread (at least, starting with Android 3.0). Thus, some way for offloading these tasks into a background thread is necessary.
AsyncTask is just a very convenient mechanism for achieving this.
See How to fix android.os.NetworkOnMainThreadException?
Thats is simple. If you download your stuff on main thread, it will block your UI and ANR dialog can show up. Your Activites are tied to XML:
setContentView(R.layout.activity_main);
But if you use Asynctask, new thread will be started, which is not related to UI. So after you start your Asynctask, you can still show anything you want, buttons will be clickable, etc. If you would download it on your main thread, user can think the application froze and quit, altrough it was just doing some calculations.
Is there any way on Android to know, if the thread running my code, is the UI Thread or not ? In swing there was SwingUtilities.isEventDispatchThread() to tell me if i am on the UI Thread, or not. Is there any function in the Android SDK that lets me know this ?
Answer borrowed from here: How to check if current thread is not main thread
Looper.myLooper() == Looper.getMainLooper()
Any Android app has only one UI thread, so you could somewhere in the Activity callback like onCreate() check and store its ID and later just compare that thread's ID to the stored one.
mMainThreadId = Thread.currentThread().getId();
Anyway, you can omit checking if you want to do something on the UI thread and have any reference to Activity by using
mActivity.runOnUiThread( new Runnable() {
#Override
public void run() {
...
}
});
which is guaranteed to run on current thread, if it's UI, or queued in UI thread.
Yes, there is a way.
Check the current thread object against main lopper's thread object. Main looper is always in the UI thread.
boolean isOnUiThread = Thread.currentThread() == Looper.getMainLooper().getThread();
Hum actually due to Android architecture, all Activities run in the main thread, ie the UI thread. So when you are coding an activity, everything that is in your Activity is in the UI thread.
That is why in Honeycomb an error have been added when you are making network calls in the main thread : it totally blocks the UI.
So by default you are in fact always working in the UI thread.
Another thing : unless you explicitely ask it to be in another thread, a Service will operate on the same thread as the activities of its application.
So, what to do ?
When you have to do heavy calculation in your activity; one solution is to use an AsyncTask (a class designed to allow you to easily use another thread). The code in onExecute() is run in another thread (but be cautious postExecute runs in your main thread). Another one is to manually start a new thread when AsyncTask is not really adapted.
If you create a service that does costly background tasks, make it run in another thread with the android:process=":my_process" attribute of the manifest. You will need to create an AIDL to communicate with this separated service, but it is not a complicated task.
Many objects, like for example the MediaPlayer, have Async variations of their methods. Try to to always use them.
Put a breakpoint where you want to check and, when it gets hit, check if you can interact with your UI (ie, if the UI is not frozen). If you can't interact with the UI then you are in the UI Thread, otherwise you are in a background thread.
In my activity, my app downloads a list of something from a website via an Http Connection. Before this list of things is displayed on the screen, I have a Loading... TextView with a little spinning ProgressBar to indicate that the data is currnetly being downloaded.
I noticed, that if I do any type of Thread.sleep() during the process of fetching the data from the web, it freezes the spinning ProgressBar.
Even if I put the method in it's own Handler Runnable so that it's on it's own thread, the animation freezing still occurs.
Is there anything I can do about this?
Yes, use AsyncTask.
A Handler is usually attached to the UI thread. Posting Runnables to it doesn't change the fact that they will run on the UI thread.
Any application should do long running tasks on a seperate thread to the UI thread as any blocking calls will not allow the UI to update.
As the other poster said, using Runnables alone do not mean the code will be executed on a seperate thread. In this case the run() method will execute on whatever thread your Handler object was created on. Either subclass Thread or pass your runnabe to new thread object with public Thread (Runnable runnable).
Using AsyncTasks, Loaders or Threads will help.
Also read Designing for Responsiveness and Multithreading For Performance. Following the above approaches will help you avoid ANRs
The reason for such a behaviour is that:
When you do thread.sleep() inside a runnable, it is the UI thread which executes that runnable rather than the respective other thread which you created. Basically what happens is that when you post any runnable through the handler of the UI thread, UI thread will poll from its queue and execute the runnable; in this case the runnable will do sleep.
Hence no change in progress bar