I will come out straight that this is a assignment question .So I am not looking for a answer but a better answer .
We have a Async Task which takes in three parameters . The progress parameter(i.e 2nd parameter is) is a Runnable .
#Override
public void onProgressUpdate(Runnable ...runnableCommands) {
// TODO -- you fill in here with the appropriate call to
// the runnableCommands that will cause the progress
// update to be displayed in the UI thread.
}
I am able to make calls to this method using publishProgress() in doInBackGround() method.
The challenge is to have this runnable attached to UI Thread. I know that onProgressUpdate() has access to UI thread and we can create a handler to add to message queue . But apparently it is excessive.
Can some guide me to a better way to do this than create a handler
If you have a reference an Activity, an easy way is using the runOnUiThread(Runnable runnable) method. Looking at the source code, it's really easy to see why:
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
If you have a reference only to a View, you can use the post(Runnable runnable) method.
The JavaDoc for both states the Runnable will be executed on the main thread.
According to the documentation
onProgressUpdate
This method can be invoked from doInBackground(Params...) to publish updates on the UI thread while the background computation is still running.
You can find a link here AsyncTask
Basically this method already runs on the UI thread. So you dont need any further code (via handelrs or runOnUiThread()).
In your case, you can just directly call run of that Runnable.
Related
I come across both runOnUiThread and Handlers, but to me its still seems to be a doubt as on which facts do they differ exactly.
What would be the best way to update UI? Should I use runOnUiThread or Handler?
Already gone through link. Still not able to justify the difference.
Thank you in Advance
runOnUiThread is a method that uses main ui handler so basically they are the same. The only difference is that if you call it inside the ui handler, you just run it instead of post it.
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
Handlers are a nice way to implement an event queue. It doesn't have to run on the main thread, you can set your own looper. RunOnUiThread is basically a shortcut so you dont actually have the initiate a handler and so on.
Handler register itself in which it is declared. or you can set the looper manually also.
Handler is particular useful if you have want to post multiple times data to the main thread.
runOnUiThread is method of Activity. so when you need to update the UI Thread, you must write the code in the following way.
runOnUiThread(new Runnable() {
#Override
public void run() {
// update the ui
}
});
So there is no re-usability.
for example you want to update the status of the file downloading. you should write the above method multiple times.
But using Handler objects update the UI multiple times using same Handler Object.
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");
}
});
I have a class AsycnIntegerCounter which extends AsyncTask, with doInBackground() and onPostExecute() overridden in the same.
From my main thread, I am able to create a runnable object and execute it using the
AsycnIntegerCounter's static execute method. AsycnIntegerCounter.execute(Runnable)
Can anyone help me in understanding what exactly happens when we execute a runnable using AsycnIntegerCounter (i.e) using AsycnTask object.
When this can be used ? and what is the advantage rather than running using a Thread object?
Code Sample:
AsycnIntegerCounter integerCounter1 = new AsycnIntegerCounter(next,0);
AsycnIntegerCounter.execute(new Runnable() {
#Override
public void run() {
int i = 100;
while(i<=105){
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
There are a couple of fundamental differences between
static void execute(Runnable)
and
AsyncTask execute(Params...)
Background task is defined in Runnable instead of implementing doInBackground
The Runnable-task is not using the internal thread communication mechanism of the AsyncTask. Hence, neither onPreExecute nor onPostExecute are called.
The latter is available on all platforms, whereas the first was added in API level 11.
The advantage of using execute(Runnable) is that the task can be executed on a worker thread of the internal thread pool, i.e. no new thread has to be created.
It's the same as execute() but it will run your Runnable in the background instead of running the doInBackround function. It can be useful when you have the same onPreExecute and onPostExecute but several runnables.
I guess the advantage over Thread.execute or an Executor is exactly calling onPreExecute and onPostExecute before and after.
#Alex makes a very good point. Suppose the you have a lot of methods, M1(), M2(), and so on that you wish to execute. Suppose that before executing any of them you need to execute method Before() and after you need to execute method After().
ie, the sequence of methods goes:
Before();
M1();
After();
Or
Before();
M2();
After();
By putting Before() in onPreExecute and After() in onPostExecute you can achieve that sequence. By making M a runnable, you can then achieve:
Before();
WhateverRunnableYouWant();
After();
With the Runnable in a background, non-UI, thread, as per your code.
As far as i figure it's like AsyncTask class but AsynchTask only runs once, but with this class it provides two things-:
It loops so it benefits, if you want a task to run multiple time
like checking for continuous data on a web service.
It fixed the running time of a task with Thread.sleep, so if a task finished
earlier it will fix the time of this task by Thread.wait().
Can anyone tell me if there's any difference between using runOnUiThread() versus Looper.getMainLooper().post() to execute a task on the UI thread in Android??
The only thing I can determine is that since runOnUiThread is a non-static Activity method, Looper.getMainLooper().post() is more convenient when you need to code something in a class that can't see the Activity (such as an interface).
I'm not looking for a discussion on WHETHER something should be executed on the UI thread, I get that some things can't and a great many things shouldn't, however, some things (like starting up an AsyncTask) MUST be executed from the UI thread.
The following behaves the same when called from background threads:
using Looper.getMainLooper()
Runnable task = getTask();
new Handler(Looper.getMainLooper()).post(task);
using Activity#runOnUiThread()
Runnable task = getTask();
runOnUiThread(task);
The only difference is when you do that from the UI thread since
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
will check if the current Thread is already the UI thread and then execute it directly. Posting it as a message will delay the execution until you return from the current UI-thread method.
There is also a third way to execute a Runnable on the UI thread which would be View#post(Runnable) - this one will always post the message even when called from the UI thread. That is useful since that will ensure that the View has been properly constructed and has a layout before the code is executed.
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);
}
});