I have read documents about Thread on Android, but I could not find differences between UI thread and Worker Thread. Can someone just give me more example about it?
The Ui thread is the thread that makes any changes required for the ui.
A worker thread is just another thread where you can do processing that you dont want to interupt any changes happening on the ui thread
If you are doing large amounts of processing on the ui thread while a change to the ui is happening the ui will freeze until what ever you have running complete.
It's partly terminology. People use the word "worker" when they mean a thread that does not own or interact with UI. Threads that do handle UI are called "UI" threads. Usually, your main (primary) thread will be the thread that owns and manages UI. And then you start one or more worker threads that do specific tasks. These worker threads do not modify the UI directly.
for example,
if we need to change UI component like change text in Text View, show toast etc , show alert then we need to use UI thread bcoz thread is just process
we can access UI in thread using runOnUiThread method
example of runOnUiThread: use this method inside thread
new Thread() {
#Override
public void run() {
//If there are stories, add them to the table
try {
// code runs in a thread
YourActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(context,"this is UI thread",0).show();
}
});
} catch (final Exception ex) {
Log.i("---","Exception in thread");
}
}
}.start();
Related
I have noticed that the main looper is called during animations, skipping over some animations if the ui thread is doing something labor intensive. One way of solving this problem is to run a thread or runnable or callable and then they join on the ui thread (automatically for callable, and manually by invoking the run on ui thread).
But does that mean that the ui thread may be interrupted during something important by the other threads?
Ie if the other thread returns some data but the ui is in the middle of doing something with the old data.
Short answer:
The main thread will finish what it is doing and will not be interupted, the other thread will post a runnable with the new data on the main thread and continue doing other stuff (if there are any), eventually the main thread will run the runnable containing the new data from the other thread.
runOnUiThread() works as follows
Runs the specified action on the UI thread. If the current thread is
the UI thread, then the action is executed immediately. If the current
thread is not the UI thread, the action is posted to the event queue
of the UI thread.
So, to understand it by using the scenario you posted it would work something like, the main thread will execute the current event that it is working with and will add your event to the event queue of UI thread.
Try this:-
runOnUiThread (new Thread(new Runnable() {
public void run() {
while(i++ < 1000){
btn.setText("#"+i);
try {
Thread.sleep(300);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}));
This question already has answers here:
How do we use runOnUiThread in Android?
(13 answers)
Closed 4 years ago.
In following code
The way we are using runOnUiThread
shouldn't this create issue with the existing UI Thread
hence creating an issue with the application , hence shouldnt be used
Thread thread = new Thread(new Runnable(){
#Override
public void run(){
//what is meant by the inside code of this run(), how is this updating the UI
runOnUiThread(new Runnable(){
#Override
public void run(){
}
})
}
})
In android,for long running task you should use separate thread such as AsyncTask() or service.Suppose you want to update your UI like you want to show any Toast to user then you should write runOnUiThread(),because only UI thread will allow to touch UI components.
getActivity().runOnUiThread(new Runnable()
{
#Override
public void run() {
Toast.makeText(getContext(), "API calling done!!", Toast.LENGTH_LONG).show();
}
});
There are two types of thread in Android.
1 is UI or Main thread on which your UI elements (layouts) are rendered.
2 is Worker Thread in which long task should be executed (like AsyncTask & Networking).
If you write some task in new Thread, that mean that task will be executed in worker thread.
Now you will use runOnUiThread or new Handler(Looper.getMainLooper()) because you can not touch UI elements in worker thread.
So basically when you are updating UI like setText(), or Toast or any UI operations, you will have to UI thread and you should use worker thread when you are doing some long executions.
Edit
Generally we don't have to manage threading in Android. Because all libraries we use are smart. Although in some cases we have to manage threading as well.
Example
Assume you are calling an web-service(api) in a new Thread, now when response comes you want show a Toast. If you just write Toast.show... directly in response inside worker Thread you will get exception.
Only the original thread that created a view hierarchy can touch its views.
Now to overcome this issue you have to use runOnUiThread, so that you can show Toast.
Whenever we have some Long running tasks we switch to some worker threads and avoid Main Thread and allow a smoother user experience and avoid ANR.
But, when the time comes to update the UI we must “return” to the
Main Thread, as only Main Thread is allowed to touch and update the application
UI.
we can achieve this by making a call to the Activity’s runOnUiThread() method:
Basically what runOnUiThread() will do is - Runs the specified action
on the UI thread. It will check the current thread and if it finds its
the MainThread it will execute that task immediately , otherwise first
it will switch you to app MainThread and then it will execute the
given task.
When a new Thread is created and executed, it does the task in the background thread. But the method runOnUiThread() is used for running the code on the main UI thread.
In your code, runOnUiThread() method is called and hence you are able to update the UI thread from the other thread.
when thread is running in the method runOnUiThread () will update the UI Components (textview .. etc..)
by calling runOnUiThread, you can update the status too
shouldn't this create issue with the existing UI Thread
Not at all. You said "existing UI Thread". There is only one UI thread. The runOnUiThread() will only add the runnable to a queue of tasks which the UI thread executed one by one. You can check the doc.
No worries! This is one of the standard way for updating UI components from a separate thread or even on UI thread itself on Android platform.
Also, runOnUiThread is an method of Activity class, it runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.
Another standard way is using Handler and Message as officially documented by Android Developer here https://developer.android.com/training/multiple-threads/communicate-ui
I've got this piece of code:
public void updateOptionLists() {
Log.d("UI", "Called update");
if (updating){
return;
}
updating = true;
runOnUiThread(
new Runnable() {
#Override
public void run() {
updating = false;
updateOptionList();
scrollToLastTapped();
Log.d("UI","Updating");
}
});
Log.d("UI", "Posted update");
}
What I'd expect from logcat would be something like this:
Called update
Posted update
Updating
As far as I know runOnUi should be asynchronous, right? And considering that the functions called alter the views, which takes a while, this should be running asynchronous. Right?
So I look at my logcat:
Called update
Updating
Posted update
Why does this happen? And how do I make sure this runs asynchronous?
runOnUiThread will execute your code on the main thread, which (in this example) also appears to be where it's called from. This explains the ordering of the log statements you see - all code is executing on a single thread, so is synchronous per the documentation (my emphasis):
Runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.
runOnUiThread is typically used to execute code on the main thread from a different (i.e. background thread). The use of this separate background thread is what will make a task asynchronous. Calling back to the UI thread at the end of that task is required if you want to modify UI with the results of your background thread calculations.
Android provides several mechanisms for doing work on a background thread and then posting back to the main thread (not all use runOnUiThread explicitly for the latter operation). Good things to read up on include Thread, Handler, AsyncTask, Service, etc.
As far as I know runOnUi should be asynchronous, right?
runOnUiThread, as the name states, runs on UI thread, which is a main thread of an application. It runs synchronously with other code running within that thread and asynchronously with code in other threads.
The word 'asynchronous' has no meaning without a context: some code can run asynchronously with other parts of the code, which means these parts of the code run in different threads. Saying that something 'should be asynchronous' makes no sense without this kind of context.
is updateOptionLists running on the UI Thread?
If this is the case, i would expect this behavior to be ok.
In a normal case you use runOnUiThread from a background thread to come again to the Ui Thread..
Because you call upadetOptionLists() on ui prosess, upadetOptionLists() and runUiThread() both run in the same thread.
To separte theam you need run content in other new thread as following
public void updateOptionLists() {
new Thread(new Runnable() {
#Override
public void run() {
Log.d("UI", "Called update");
if (updating){
return;
}
updating = true;
runOnUiThread(
new Runnable() {
#Override
public void run() {
updating = false;
updateOptionList();
scrollToLastTapped();
Log.d("UI","Updating");
}
});
Log.d("UI", "Posted update");
}
}).start();
}
For accessing the view, you must be in the UI Thread (the main one). So, runOnUiThread will be executed on it.
You must do the long work in an other thread and only call runOnUiThread for little thing like changing a color or a text but not to calculating it.
From the documentation:
Runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.
http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)
Multi Threaded Programming: Theory vs Actual
Puppy Photos Explain is the Best pic.twitter.com/adFy17MTTI— Cian Ó Maidín (#Cianomaidin) 6. april 2015
But joke aside.
If you want to test how the threads work in correlation, try:
runOnUiThread(
new Runnable() {
#Override
public void run() {
updating = false;
updateOptionList();
scrollToLastTapped();
Thread.sleep(100);
Log.d("UI","Updating");
}
});
My question Is that What is the difference between Thread and Handler
Q1) What are their effects When they are used in 1) Activity 2) Service
Q2) What is difference between them in context with their life span
I am using following codes for them.
1) ---------------------------
final Handler handler = new Handler();
Runnable runnable = new Runnable()
{
public void run()
{
// do somthing
handler.postDelayed(this, 1000);
}
};
runnable.run();
2) ---------------------------
handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
}
};
new Thread(new Runnable()
{
public void run()
{
while(true)
{
try
{
Thread.sleep(1000);
handler.sendEmptyMessage(0);
} catch (InterruptedException e) {}
}
}
}).start();
Handler:
handler is used to do looper thing.that is to perform same task number of time.
handler can be executed on main thread.
about Handler if its used in service it may get stop if phone state change to sleep.
u can update the UI through handler if it used in activity.
Thread:
Thread is used to things on separate than the main thread of an activity.
thread always runs in background even if phone state changes to sleep mode.
u cant update the UI of as its not running on main thread.it can be done using asynctask not using simple java thread.
Q0) What is the difference between a thread and a handler?
A Thread is the same as it always is in programming. Each thread executes a single call to a method and then terminates. Each thread runs in parallel with every other thread. Threads are in short the way you have more than one thing happening at once.
Passing information between threads is notoriously difficult...
A Handler is Android's way of passing a message from one thread to another. Specifically it allows you to pass a set of instructions as a Runnable into a thread for that thread to execute. Typically they are used as a way for a thread to report its result back to the main thread when it's complete.
Q1) What are their effects When they are used in 1) Activity 2) Service
There is no difference between the way these two items behave in a service or an activity in general except that a service can exist in its own process if android is instructed to do so. Threads in different processes can not directly talk to one another. Services are there to share data,functionality and in some cases threads between activities. There is no requirement for them to have their own thread.
The one major point to note is that only the main thread can update the UI (activity).
Also networking specifically can not be done on the main thread. Networking is usually done from within a service so that the results can be shared but this is not necessary.
The limitations around what must and must not be done in the main thread make threading a little tricky, but these limitations are there to help you avoid freezing the UI unexpectedly.
Q2) What is difference between them in context with their life span I am using following codes for them.
Difficult to answer as I don't understand the purpose of your code.
As an example. Android no longer allows you to do any networking on the main thread as this could freeze the UI while it's waiting for the server to respond over a poor wifi connection. To change something on the UI based on something retrieved from the network you must use a thread to do the networking and pass the data back to the main thread to update the UI.
A (doctored) snippet from my code looks like this:
private final Handler handler = new Handler();
#Override
protected void onCreate( Bundle savedInstanceState ) {
// irreverent to the example
super.onCreate(savedInstanceState);
super.setContentView(R.layout.abstract_main_view);
// Here's the example
Thread networkThread = new Thread() {
#Override
public void run() {
// This could take several seconds
final Collection<Player> players = service.lookupAllPlayers();
Runnable uiUpdate = new Runnable() {
#Override
public void run() {
// This is quick, just adding some text on the screen
showPlayers(players);
}
};
handler.post(uiUpdate);
}
};
networkThread.start();
}
In this example:
The handler is created and exists for the duration of this activity. Because this class is constructed by the main thread, the Handler is also. This means that all messages posted to this handler will be executed by main.
networkThread is created and started by the main thread in onCreate. This lives until it has retrieved the data from the network and posted a response back to the main thread. Then it's done.
The Runnable uiUpdate is created by networkThread once all data is retrieved. It does not have a thread associated and so does not execute right away. Instead it is posted back to main using the handler. It is then executed on the main thread and discarded once complete.
One can use a Handler to inform one thread of events from another thread.
Typical usage would be to inform the UI Thread from other threads.
We can not modify UI elements from other threads directly. So we can define a Handler as a member of an Activity instead.
Activities are created on the UI Thread so this handler also is on UI Thread.
So then from another thread we send a message to the Handler. And on receiving the message the Handler modifies some UI elements.
In my Android app, I am extracting the code to update UI elements into a separate utility package for reuse. I would like my code to be proactive and update the UI differently if the current execution context is from a UI thread versus a non-UI thread.
Is it possible to programmatically determine whether the current execution is happening on the UI thread or not?
A trivial example of what I am looking to achieve is this - my app updates a lot of TextViews all the time. So, I would like to have a static utility like this:
public static void setTextOnTextView(TextView tv, CharSequence text){
tv.setText(text);
}
This obviously won't work if called from a non-UI thread. In that case I would like to force the client code to pass in a Handler as well, and post the UI operation to the handler.
Why don't you use the runOnUiThread method in Activity
It takes a runnable and either runs it straight away (if called from the UI thread), or will post it to the event queue of the UI thread.
That way you don't have to worry about if your method has been called from the UI thread or not.
When you're not sure the code is executed on the UI thread, you should do:
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
// your code here
}
});
This way, whether you're on the UI thread or not, it will be executed there.
You can use the View post method.
Your code would be:
tv.post(new Runnable() {
public void run() {
tv.setText(text);
}
});