Given that posting a task with post() puts the Runnable in a queue, is there any difference between
protected void onCreate(Bundle savedInstanceState) {
Log.d("UI thread", "Do something");
}
and
protected void onCreate(Bundle savedInstanceState) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Log.d("UI thread", "Do something");
}
});
}
?
In both cases, there should only be one thread running and no concurrency happening - right?
Then what's the benefit in creating a handler that attaches to the UI thread and running tasks on it?
The timing is different. In the first snippet the code is executed as part of the onCreate execution so it is guaranteed to finish before onCreate returns, in the second snippet, it is executed some time later (maybe after several other callbacks).
Then what's the benefit in creating a handler that attaches to the UI thread and running tasks on it?
Your example provides only a minimal "use case" which most developers may never experience. In your example, you might want to start a background service but you wanted to ensure that the method that starts the service completes before performing that work, your example would accomplish that. Additionally, you might want to ensure that the service construction is prioritized on the main/UI thread. This approach means you don't have to add a comment like "put this code at the end of this method" or have other "inherent code dependencies" - the call to the handler guarantees post-method/end of method execution. Not really "normal" so...
A more useful example is when you have a background thread that needs to update the UI. It can do the necessary processing in the background, then create a handler that will execute on the UI thread appropriately. This is very common and is implemented in AsyncTask for example (in its getMainHandler() method - https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/os/AsyncTask.java#L282)
Also, handlers allow for post-delayed execution of Runnables. A post-delayed execution is often beneficial for situations where immediate screen display is more important than complete screen display. In most cases a developer should "bake-in" a delay and have the screen show a loading spinner or some other UI/UX decoration, but if there isn't a requirement to specify the length of the delay, the example you gave would post the runnable on the main thread looper queue to execute ASAP. That might be exactly what you want to do, or it might be confusing to other developers that might have to maintain your code (for example, the reason you asked this question).
Related
This is not the problem about being able to call a method in the main/UI thread but being able to do so instantaneously.
It is my knowledge that you are not normally allowed to interact with the UI thread directly because of the UI responsive requirements. It would make sense then to have a system in place to queue the requests you have for the main thread and we do have that system with the looper, handler, etc.
Here is what I did:
I did some task in the background thread and I want to intimate the main thread as soon as a condition gets satisfied(I created a listener for it) and I use the response handler to post it..something like this:
if(mNoOfPendingRequests >= mNoOfRequestsConsideredEnough){
mShouldFlagEnoughRequestsAtATime = true;
Log.i("ThumbnailDownloader: ","Enough Requests Queued");
//Now inform about this to PhotoGallery right now
mResponseHandler.postAtFrontOfQueue(new Runnable() {
public void run() {
mEnoughRequestsListener.onEnoughRequestsQueued(mShouldFlagEnoughRequestsAtATime);
}
});
}
else{
mShouldFlagEnoughRequestsAtATime = false;
mEnoughRequestsListener.onEnoughRequestsQueued(mShouldFlagEnoughRequestsAtATime);
}
If I don't inform the PhotoGallery about the enough requests sent already, it would continue to send more and more requests and app becomes unresponsive.
Also, the requests are queued and are executed later resulting in too many requests.
My question is therefore:
Is there a way to call a method/inform in UI thread from a background thread almost instantaneously?
You can run things on UI thread doing this:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// put your code here :)
}
});
Is there a way to call a method/inform in UI thread from a background thread almost instantaneously?
Not really. Your postAtFrontOfQueue() is about as close as you can get, and as the boldface note mentions in the docs, "This method is only for use in very special circumstances -- it can easily starve the message queue, cause ordering problems, or have other unexpected side-effects."
If I don't inform the PhotoGallery about the enough requests sent already, it would continue to send more and more requests and app becomes unresponsive. Also, the requests are queued and are executed later resulting in too many requests.
Have more smarts in your queue, to know when to throttle back request processing based upon whatever your "enough" algorithm is.
This method works like a charm unless you already have lots of events in your events queue.
activity.runOnUiThread(new Runnable() {
public void run() {
// call your method here
}
});
Yes, you can call using activity context
runOnUiThread() and pass runnable object and write code inside run() method.
It is not clear from your code, what onEnoughRequestsQueued does. If all it is doing is telling the posting thread that it should stop sending requests, then you can probably accomplish the same thing with a simple volatile boolean
If the thread enqueuing requests stops doing so, when the variable is true, and the background thread sets it true, and the variable is volatile you should be good.
Is there any callBack to setContentView in Android, since i'm doing a heavy operation right after setContentView line, and it seems to skip that setContentView.
So i was thinking of moving the heavyOperation to the callBack of setContentView.
Thanks
EDIT:
Pseudo Code:
AudioRecord Finishes
SetContentView(1) //To show a "Processing" screen with no buttons
FFT analysis
SetContentView(2) //On FFT analysis DONE.
In my case "SetContentView(1)" NEVER occurs.
EDIT # 2:
I did the heavy operation in another Thread, and used Handler to send a Message after heavy operation finishes to treat it as a callBack.
Thanks for all the help guys
Short answer: No callback for the setContentView.
If you are doing network operation then you can use the AsyncTask for this.
If you are doing any more heavy operation and want to update the UI then you can do that using the Service and BroadCastReceiver.
For this you have to make your own callback using the interface.
heavy work should be done in asynk tasks or as a service or on other threads
Don't do any heavy calculations on the main UI thread where onCreate() and such are run.
What happens that the first setContentView() posts a "layout and draw" message to the UI thread message queue. Then your calculation blocks the UI thread, preventing messages in the queue from being processed. The second setContentView() posts another message to the queue. When the control eventually returns to the message loop, both messages are processed and you'll get the layout set up by the last call to setContentView().
For heavy computations, use a separate thread. For example, an IntentService or an AsyncTask make threading easier.
My hack.
final Handler handler = new Handler();
setContentView(layoutResID); // This posts some messages to message queue.
handler.post(new Runnable() { // Post another message at the end.
#Override
public void run()
{
// Called after layout has changed.
// If you want to skip some more works (like transitions),
// call another handler.post() here.
}
});
To see what happens, set a break point at the line Message msg = queue.next(); in Looper.loop() may help.
I was facing a quite similar problem a day ago, but I figured it out. (I know your problem is solved, just offering a different approach which doesn't require a handler or callback.
Most Suitable for running U.I. functions :
If you need to do something like this :runTask() then
setContentView() (or any other ui function) you can run the task on different thread by using AsyncTask or you can set a timer for when the task is completed (if your task takes a certain time), the User Interface functions will be called.
But since the Timer class, runs the functions on a different thread, you can not run the setContentView() inside it. So you can use a runOnUiThread(Runnable action) method inside the overloaded run() function of Timer class. You just need to define a function that returns a runnable. Define your Ui operations in the runnable action.
Hope it helps someone.
I want to ensure that I don't slow down my app's startup time and need to start a background task that's unrelated to user input--for instance, filling a cache.
If I start an AsyncTask from my onCreate method, when will the doInBackground method actually begin to execute? (Assume a single core device)
Is it possible that Android could schedule it before onCreate/onResume has completed, or is it smart enough to recognize that the background thread shouldn't run until the UI thread is completely finished?
If you look at AsyncTask source code you will see that it is just using ThreadPoolExecutor or serial executor for running tasks. Default internal behavior depends on Android version (from AsyncTask docs):
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
But anyway doInBackground execution is not connected with Activity lifecycle so AsyncTask may be executed at almost any time. This depends only on how many tasks you have already started, on default Executor which is used by AsyncTask and on thread scheduler.
I usually use AsyncTasks in onCreate() like this:
private MySuperSpecialTask mySuperSpecialTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(...);
// [...]
mySuperSpecialTask = new MySuperSpecialTask();
mySuperSpecialTask.execute();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mySuperSpecialTask != null) {
mySuperSpecialTask.cancel(true);
}
}
This makes sure that everything is initialized before the task gets started.
actually strictly speaking there is no execution order of your UI code and starting the asynctask I found out. Normally one does not experience this, however, if your UI thread takes longer for some reason, eg waiting for external input etc, the asynctask might have gotten started BEFORE UI code has finished.
Writing UI code is just a request to the Android system and this waits in the execution loop. So if asynctask starts before that because there are enough ressources (or as mentioned UI thread is delayed for whatever reason) there is no execution order guarantee.
One easy way to enforce this is - in case you don't mind and you can be sure that it is suffiencient - delay the starting of the asynctask with ScheduledExecutorService or a "cleaner" way would be to implement some kind of gate keeper that waits for a flag to be set to true and then start the asynctask. Or you may even have a while-loop at the beginning of your asynctask that waits for the flag to be set to true, like in many communication situations with external devices.
The flag would be set to true AFTER you can be (normally) sure that your UI has finished.
I am writing an android app and I need to be able to do certain things periodically/continuously. I am coming from a C/C++ embedded firmware background and this new-fangled way of doing things is going to take some getting used to. It seems that there is no such thing as a "main loop" in Android, that everything is event-driven... I also understand that by default all code you write operates on the GUI thread, and I should probably make a new thread to execute the equivalent of a "main loop"...
So far what I have is an implementation of the AsyncTask class who's "doInBackground" method contains an infinite loop (my main loop), I create an instance of this class and run it immediately when my app starts. The problem I am having is in the interaction between this thread and the user interface... when something occurs in my main loop thread and I want to update the GUI understand that I must call "publishProgress", which is executed on the GUI thread. There are a few problems with this, primarily that many things I have tried to do in this "onProgressUpdate" method do not work, or do not occur in a predictable amount of time.
My question, is there a better way to accomplish what I am trying to do? In general, what do most people do when they have code that they want to run periodically and/or continuously while their application is running, code that must interact with the user interface in a timely manner (by timely I mean with zero delay).
Thank you.
public class MainLoopThread extends AsyncTask<Void, Void, Void>
{
#Override
protected Void doInBackground(Void... arg0)
{
while(true)
{
//Do stuff
//Update GUI
publishProgress();
}
}
protected void onProgressUpdate(Void...voids)
{
//Update GUI
}
}
It is unclear what you are trying to do, however just let me say using AsyncTask in this way may have negative consequences.
AsyncTask internally uses a thread pool pattern for running the stuff from doInBackground(). On Android OS before 1.6 and starting from 3.0 the pool size is just 1, meaning no parallel computations for a bunch of AsyncTasks. More details on this here.
So, this may result that only this current AsyncTask is running, while others even if started will have to wait untill the current one is done.
Depending on your needs for things to be done periodically Android exposes:
AlarmManager
Handler - it allows to post a runnable on UI thread with a delay or periodically
Timer + Activity.runOnUiThread(Runnable action) inside of TimerTask
UPDATE: basing on your comments it looks like you need a Service, that starts a thread that periodically sends broadcasts with the data for UI. Then your UI (Activity) registers broadcast receivers to catch those broadcasts, extract the data and use for UI updates.
So your saying that onProgessUpdate() isn't working? That seems weird because it should.
Another option that you have is just to make a Thread that loops.
The trick is that if you want to update the UI thread you will have to make a call to view.post() and give it a runnable that will actually perform the update. The idea here is that you must schedule an update on the UI thread, you can't just take it and say NOW!
There have been a number of questions regarding the proper usage of Threads vs. Handlers vs. AsyncTask. (like here & here)
Those questions nicely addressed the question of when to use what. My question is more about the performance implications in certain types of cases.
As an example, I often see other people write code in which they use Threads simply to be able to schedule some code execution for the future. Whenever, I see this, I instinctively feel like refactoring the code to use a Handler and just a post a delayed runnable.
Here's an example where a Thread is used to update the seekbar for some media playing with a mediaplayer and then the way I would do it.
what I see a lot:
if (positionTracker != null && positionTracker.isAlive()
&& !positionTracker.isInterrupted()) {
return;
}
positionTracker = new Thread(new Runnable() {
public void run() {
int currentPosition = 0;
int total = player.getDuration();
while (player != null && CurrentPosition < total) {
try {
Thread.sleep(1000);
currentPosition = player.getCurrentPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
if (someListener != null) {
someListener.onEvent();
}
}
}
}, "position tracker thread");
positionTracker.start();
And the way I like to do it:
Runnable trackPositionRunnable = new Runnable() {
#Override
public void run() {
currentPosition = player.getCurrentPosition();
if (someListener != null) {
someListener.onEvent();
mHandler.postDelayed(this, 1000);
}
}
};
mHandler.post(trackPositionRunnable);
Obviously, my preferred way is a bit easier to read and more concise. But what are the performance implications? Is one way method better, in terms of performance, than the other? If so, why?
Each method depends on what you plan on doing in that Runnable as to whether it will be useful or not. The biggest difference between them all is whether you plan on touching the UI or not. In Android you can't touch UI components off the UI thread (your example of media player is breaking this rule with raw Thread). Because of this rule that immediately divides what you can and can't do with each method. Performance differences between these methods is negligible because time spent running your background job is going to trump any differences between them.
Handler typically use another background thread to execute logic in, but it depends which thread constructed the Handler. If the Handler was constructed on the UI Thread (in response to callback onSomething) then your Runnable will run inside the UI Thread making it ok to touch UI Components. However, if you created it off the UI thread Runnables posted to it CANNOT touch UI components. The downside to Handlers created on the UI thread means you aren't doing these in the background so if a job takes a long time to run it will lock up the UI until its done. While Handlers run from non-UI threads will fix the any issue of locking up the UI. They take more work to setup and you still have to contend with how to safely update the UI in response to your background job (ie you still have to post another runnable back to the UI Thread if you want to update the UI).
Raw threads won't lock up the UI because they are running independently from the UI thread, but you can't touch UI components on them. That means you'll have to execute any code you want to update the UI with back on the UI thread which means more code needs to be written to get the UI thread to run it. This can be very complex. Raw threads should really be avoided because of the complexity in using them.
The most common example of background tasks is waiting for a response from the server. Most libraries block until the server sends a response which means you can't call them on the UI thread or else your user will be blocked from doing anything until the server returns a call. Not only will they be blocked, but the UI can't update itself to show a spinner or otherwise look alive. This is best to push off to a background thread. Technically Handlers and Threads can do this, but Handlers have to be constructed specially so they will use a true background thread.
This is where AsyncTask trumps Handlers because it does both true background jobs and UI updates. It has a section for doing some long running operation in the background and it has a section for updating the UI from the UI thread when its done. It even has an optional progress section so you can provide any intermediate progress to the UI while the task is running. The downside of an AsyncTask is that they must have an end. Background jobs that continue to run to periodically check if something has happened, sleep and check some more aren't conducive to the AsyncTask model. However, that's not to say you couldn't use a Handler to periodically kick off AsyncTask, but just for the completeness of the discussion I mention that.
In the end using raw Threads isn't all that easy or even "better" because Handlers can do pretty much anything that Threads can do with less code. But, Handlers are tricky in determining which thread the Runnable is executing on. Most often it's the UI thread, and technically setting it up to use a non-UI thread is tricky. Both options suffer from the UI update issues in that you have to do extra work to run UI jobs at the end of true background jobs. AsyncTask is really my preferred method for doing background jobs.
It is not Handler vs Threads. They are quite different things:
Thread: Is the old Java class that implements a thread of execution. As other parts of the Java APIs they are also available on Android. Notice than in late versions of the Java language they were superseeded by the Executors framework, so the recommended practice is to use Executor/Runnable, but due to it's simplicity Threads are still used sometimes.
Handler: This class is available only in Android, and it is mostly a mechanism to communicate with an existing Thread. You send the target thread Messages or Runnables, and you can also schedule this communication.
You usually need a Handler when you need to send something to a thread. This "something" can be, for instance, encapsulated data to be processed, or a Runnable to be executed in that thread. Every handler is usually associated to the current thread at the time of instantiation, unless you use a more exotic constructor. A typical use case is to schedule a repetitive task in the main thread (which is the UI thread). Notice that for scheduling a one-shot task there's an easiest way: Activity.runOnUithread.
Now for a background task that needs to be run in a thread different than the main one: in both approaches you'll have a thread running, but creating a handler means that Android will start a new Message Queue for that thread, which is something regular threads do not need to have, and because of this there will be some overhead. Thus if you need to start a thread that can run isolated without receiving information, i'd say the simple Thread is preferred. But if you need an execution queue to schedule Runnables you can choose between a Timer, an Executor, a "handled" thread, or even AlarmManager. The advantage of Handlers is that they can be attached to any already existing thread in your app, while Timer and Executors will internally launch a new dedicated thread when they are set up.
Correctness: Your first example is fraught with peril, since a MediaPlayer must be created on a thread with its own Looper and operations from any other thread may cause errors. Similarly, since your someListener.onEvent() is presumably updating a UI, it had better know to post to a handler on the UI thread anyway.
Performance: I have no measurements to offer, but in your example, the runtime cost is (thread switching) + (handler overhead), versus just (handler overhead). So for any thread switching overhead > 0, the threads are more expensive. On the other hand, if your entire application is coded in your favored style, and any piece of your code is slow and synchronous, you just made your application feel laggy.
Which is why anything potentially slow or synchronous needs to head toward the thread (or service) style, despite feeling more complex and error-prone. Your particular MediaPlayer example is not a perfect poster child for making this case.
If you're dealing with threads, I suggest that you use a handler together with it:
Handler handle = new Handler();
Thread new Thread()
{
#Override
public void run()
{
try
{
handle.postDelayed(new Runnable()
{
#Override
public void run()
{
"your code goes here"
}
},delay);
}
catch(Exception e)
{
e.printStackTrace();
}
};
}
That way you can delay the execution for as long as you want, or you can use post and Thread.sleep(delay), which I prefer these days.