When RoboGuice fires Event, where will my event callback be executed, in which thread?
For example, I have an activity which has do(#Observes OnUpdateUiEvent e). I also have a background thread which fires new OnUpdateUiEvent("data"). So, my do() method will be executed in bg thread as I understood? What will be, if I annotate do() with #Background from AndroidAnnotations? Should preprocessor make call to do() in runInUiThread()?
If everything is right, I think this pattern will provide the easiest way of communicating between threads.
As far as I can see here and there, you can specify the way threads should mix with events in RoboGuice, by using #Observes(EventThread.CURRENT), #Observes(EventThread.UI) or #Observes(EventThread.BACKGROUND).
The default is "CURRENT", which means that if you didn't specify anything, the event listening method will be executed in the same thread as the method receiving the event.
So yes, if you fire your event from a background thread, do() will be executed in a background thread.
If you add #Background on the do() method, then it will always be executed in a separate thread, different from the one where you fired the event.
If you're not sure, put a breakpoint and watch the thread names :-) .
Did that answer your question?
Related
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 test if my Looper finished its work because I want to execute code after all elements of my activity are on screen. I want to trigger an event after Looper finishes its work. Can I do that or is there any another way to execute my code after all elements in the UI appears on screen?
Once you started a looper by calling Looper.loop() it does not exit until you explicitly call Looper.quit().
You can use Semaphore to coordinate your code, so you can wait until the Looper finish its work.
1- define a Semaphore object in your class and initialize it with 0 permits, e.g.
Semaphore semaphore = new Semaphore(0);
2- In the place where you want to wait call semaphore.acquire(), which will block until a permit is available
3- After you finish your looper call semaphore.release(), which will add a permit to the semaphore and the other waiting code will continue to run.
Note, that if the looper finished before semaphore.acquire() is called; it will continue immediately and will not block
See my answer here, for a code example on using Semaphore
You can check the visibility of your elements. If they're true,run your code.... (Hope I understood right.)
This may have been hidden somewhere in the docs, but I don't remember seeing it:
Assuming everything is running on the same thread, would an activity callback, or any kind of callback for that matter, interrupt a runnable , or even some other callback, executing on the thread, or are they posted sequentially by time of occurance as messages similar to runnables?
It certainly doesn't interrupt execution, at least in the UI thread. For instance, say that you have a Button, and you place a Thread.sleep(10000) in its onClick callback. Well, as soon as you press the button the entire UI will freeze. This wouldn't happen if the onClick callback interrupted the UI thread's execution.
If you wanted to know all the answer of the question you need to use
http://developer.android.com/guide/developing/debugging/debugging-tracing.html
Depends on the Runnable.
All activity callbacks happen in the UI Thread. For example thread for onCreate is same as the thread which calls onTabSelected.
If you are started an AsyncTask, it runs in its own thread.
Try using following Log statement to check your scenario
Log.i("","Thread Id : "+Thread.currentThread().getId());
I am updating an activity's UI from a BroadcastReceiver that I register in the same activity. The API docs say:
[...] The function [onReceive()] is normally called within the main thread
of its process [...]
so I suppose updating the UI is okay.
The docs also say:
[...] you should never perform long-running operations in it (there is
a timeout of 10 seconds [...]
I am just setting some text on a TextView so I suppose that won't ever take longer than 10 seconds.
But, and here comes finally my actual question: Does it make any sense at all to add a Runnable to the main thread's message queue using a Handler, so that onReceive() can return immediately and the UI update happens at some later point in time, as the docs suggest:
There are two main uses for a Handler: (1) to schedule messages and
runnables to be executed as some point in the future; [...]
?
If you're just setting text on TextViews then you won't have issues. No need to over-complicate things with Handlers.
Though I will say that some people like using handlers just because it keeps things organized if multiple calls to a specific UI method need to be called. Using a handler will guarantee that that executed code will be initially placed on the UI thread, so it avoids having to check which thread you are running on.
The important thing to keep in mind is that all UI actions should be performed on the UI thread, and any sort of intensive processing should be done on a background thread.
Yes, using a Handler to schedule a Runnable is the standard.
Can someone explain to me what exactly the UI thread is?
On developer.android.com it says about the runOnUiThread function
public final void runOnUiThread (Runnable action)
Since: API Level 1 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.
Does the UI thread mean that this will be run everytime the activity is pushed the the background by some ui activity like incoming call or screen dimming etc.? If not, what exactly does the UI thread include ?
Thank you
The UIThread is the main thread of execution for your application. This is where most of your application code is run. All of your application components (Activities, Services, ContentProviders, BroadcastReceivers) are created in this thread, and any system calls to those components are performed in this thread.
For instance, let's say your application is a single Activity class. Then all of the lifecycle methods and most of your event handling code is run in this UIThread. These are methods like onCreate, onPause, onDestroy, onClick, etc. Additionally, this is where all of the updates to the UI are made. Anything that causes the UI to be updated or changed HAS to happen on the UI thread.
For more info on your application's Processes and Threads click here.
When you explicitly spawn a new thread to do work in the background, this code is not run on the UIThread. So what happens if this background thread needs to do something that changes the UI? This is what the runOnUiThread is for. Actually you're supposed to use a Handler (see the link below for more info on this). It provides these background threads the ability to execute code that can modify the UI. They do this by putting the UI-modifying code in a Runnable object and passing it to the runOnUiThread method.
For more info on spawning worker threads and updating the UI from them click here
I personally only use the runOnUiThread method in my Instrumentation Tests. Since the test code does not execute in the UIThread, you need to use this method to run code that modifies the UI. So, I use it to inject click and key events into my application. I can then check the state of the application to make sure the correct things happened.
For more info on testing and running code on the UIThread click here
If you execute blocking code (e.g. a Http-Request) in a separate Thread, consider using AsyncTask. Its doInBackground-Method runs on a separate Thread. AsyncTask provides you with methods onProgressUpdate and onPostExecute which are guaranteed to run on the UI thread.
If you need GUI-progress updates (e.g. via a progressbar) call publishProgress inside doInBackground. This leads to a subsequent call of onPublishProgress which is also guaranteed to run on the UI thread.
onPostExecute is automatically called after doInBackground returns.
All UI drawings etc. happen in a separate thread. Its called the UIThread. If you want to make any change to UI u must use make sure it happens in UIThread's context.
Easiest way of doing it is to make use of runOnUiThread