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.
Related
All over the web and on Stack Overflow there are references to the UI Thread's Event Queue. For example runOnUiThread() will post an action to the UI thread's Event Queue. But I haven't been able to find a detailed description of this queue, so could someone please point me to a detailed one, or answer a few questions?
1. I get that it's a queue and that it contains "actions", but I'm a little unclear what an "action" is. Are actions method calls with their associated parameters, or instructions to the thread itself, or what?
2. Do all threads have event queues or just the UI thread?
3. How can I see what's in the Event Queue, or get a count of events?
4. What exactly determines when an action in the queue is executed?
5. The View class has a method called cancelPendingInputEvents() which is used to "Cancel any deferred high-level input events that were previously posted to the event queue." If the event queue is a property of a thread, why is this a method of the View class, or do views have some different Event Queue?
6. Are the message queue and event queue two different queues? N.B. - someone asked this on SO here and the answerer started by saying they were synonymous and then appended an addendum which seemed to imply messages were different so I'm unclear what the final answer was.
it's a queue with Runnables. The thread calls run(); on each of the runnables.
only threads that called Looper.prepare(), so any thread can potentially have them. There's an Runtime Exception for that "Can't create handler inside thread that has not called Looper.prepare()"
You can't. Stuff is managed by the platform and calls Activity callbacks, Fragment callbacks, dispatch touch events, run animations, run layout, measure and draw. All this in the UI thread.
AFAIK it's a FIFO. But I might be wrong on that one.
Views have a Handler to the UI thread. Handlers are bound to the thread and it's MessageQueue. That's how you can create a new UI thread handler by calling new Handler() on the UI thread. And then post stuff to that thread queue by calling handler.post(Runnable)
I don't believe they're different. But would have to dig on source code to be sure.
It's always helpful to read the docs:
https://developer.android.com/reference/android/os/Handler.html
https://developer.android.com/reference/android/os/MessageQueue.html
It's just a standard message loop, like every GUI platform uses. "Event" is a CS term, not a particular object. Imagine that inside the Android framework you'd see something like this:
MessageQueue queue;
void run(){
while(1){
queue.waitForEvent();
Message msg = queue.getEvent();
//Handle msg
}
}
Only the UI thread has an event loop, although you could write your own on another thread.
You cannot see the event queue or get a list of events. The ones you need to know about will call some function in your code
Events are executed as soon as the thread can. If there are no events in the queue, the thread sleeps. They should be executed in order, although the framework may cheat on some events.
A message queue and event queue are the same thing. There's also a class called MessageQueue, which is not the same as the queue we're talking about here but which may be used to implement one.
Why can an AsyncTask perform only one job? For example,
task = new SubAsyncTask(...); // assume the parameter is correct.
task.execute(...) //
task.execute(...)// calling once again, it throws exeception.
But a Handler can continously perform more than one task:
hd = new Handler(...); // assume the parameter is correct
hd.sendMessage(...); //
hd.sendMessage(...);// no exeception is thrown.
Is an AasyncTask object for a one-time job only? If I don't want to create multiple object for similar task, should I choose Handler?
Handler and AsyncTasks are way to implement multithreading with UI/Event Thread.
Handler allows to add messages to the thread which creates it and It also enables you to schedule some runnable to execute at some time in future.
Async task enables you to implement MultiThreading without get Hands dirty into threads. Async Task provides some methods which need to be defined to get your code works. in onPreExecute you can define code, which need to be executed before background processing starts. doInBackground have code which needs to be executed in background, in doInBackground we can send results to multiple times to event thread by publishProgress() method, to notify background processing has been completed we can return results simply. onProgressUpdate() method receives progress updates from doInBackground method, which is published via publishProgress method, and this method can use this progress update to update event thread, onPostExecute() method handles results returned by doInBackground method.
So, you dont need to call execute method on AsyncTask multiple TImes, instead you can invoke publishProgress.
Because that is how the class was designed. The idea is: do something with UI (show progress dialog, etc.), do work on background thread and return results, update UI. The Handler is fundamentally different: it lets you post messages, but it does not create a background thread for you. If you don't like how AsyncTask works, build something similar by using threads/executors and handlers.
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.
I tried to look clear answer for it but wasn't able to find it anywhere. I am running background thread in main activity that checks for certain variable and if it is true it should show alert dialog. I also want this dialog to show up on any focused activity of the application. I tried it by adding Looper.prepare() and Looper.loop() to the thread but it does not work properly and it affects while() loop that I use to check variable in that thread. Can anyone please help me in finding out what is the best way to implement this?
Thanks.
If you construct the background thread using the main/ui thread, you can create a Handler in the constructor. When you want to run some code on the main/ui thread, you simply Handler.post(Runnable r) with a runnable to the ui thread.
If your background thread is not being constructed on the ui/main thread, you can use a BroadcastIntent to and a BroadcastReceiver pattern to send messages between your background thread and your foreground activities. This is especially useful if you are switching foreground activities during the useful life of your background thread.
You may want to try creating an implementation of Runnable and passing that to a View's post() method.
final Runnable r = new Runnable() {
public void run() {
//code to display dialog
}
}
final View view = findViewById(R.id.XYZ);
view.post(r);
This will run the Runnable on the UI thread.
Ok, i can see two approaches. The first one is a dirty but quick:
You can extend TimerTask and Handler classes. YourTimerTask will check variable and send a Message to YourHandler. YourHandler should override handleMessage and show a dialog.
The second one might be an overkill, but still. Android is event-based. It means that system gives you an opportunity to create your own events and handle it. So, you can start a Service, which will check your variable and send a Broadcast (can be local). In your activity you have to create your own BroadcastReceiver and register it. This receiver will handle a message.