I already have idea on how to use a Progress Dialog when background action is being performed. But my question is how do I show a progress Dialog when I am dynamically inflating a huge layout.
Since I can't inflate a view in another Thread, I am using the main UI thread. Due to this my progress dialog is not getting priority and it doesn't show up. My UI hangs for several seconds until it gets loaded fully. I tried several approcahes but none seems to work.
progress.show(context,"","inflating UI...");
setNewContent(R.layout.my_profile,R.id.my_profile_menu_button,R.id.my_profile_all_elements_layout);
populateProfileList(); //Dynamic nested layouts being inflated.
I am basically looking for dynamic layout changes based on user actions. So I dont have any other way other than creating dynamic views. Can anyone suggest me a helpful idea.
I had an similar problem with ui-thread. I wanted to add much views to my layout at runtime, I wanted to show a ProgressDialog to inform the user, that it could take a while. I had tried it with AsyncTask, but the only chance to do this, was to implement my ui-methods into the onPostExecute-Method of AsyncTask. But this just freezes the ProgressDialog, because ProgressDialog even works on ui-thread. I found a solution, maybe not the best, but it works. Before starting ui-action, I show a Toast. Then, I created a Thread with a handler and delayed the execution. After ui-action was done, I showed a new Toast. Delay the thread, gives the Toast enough time to get showed:
Toast.makeText(ActivityContext.this,
R.string.start_message,
Toast.LENGTH_SHORT).show();
final Handler uiHandler = new Handler();
final Thread uiThread = new Thread(new Runnable() {
#Override
public void run() {
uiHandler.postDelayed(new Runnable() {
#Override
public void run() {
yourUIAction();
Toast.makeText(
ActivityContext.this,
R.string.finish_message,
Toast.LENGTH_SHORT).show();
}
}, 100);
}
});
uiThread.start();
You need to use a handler to be able to talk to the UI thread
//in some thread
uiHandler.sendEmptyMessage(1);
...
Handler uiHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
if(msg.what == 1) {
//do somestuff
}
}
};
Using Async Task is much better idea to me, when you have to do something in background, while progress dialog shows up on screen and then when background task completes, update UI... for reference please follow the link...
http://labs.makemachine.net/2010/05/android-asynctask-example/
hope this helps...:-)
Related
I've found that a lot of people are having a similar problem but I am simply trying to show a dialog while I am grabbing some data off a URL and then dismiss properly after the data is retrieved. Here is what I'm trying to do (This is in my onClick() method for a refresh button):
dialog.show();
// do some work
dialog.dismiss();
Doing it this way you never really see the dialog at all. I've tried doing it using an extra thread such as:
Thread t = new Thread() {
public void run() {
dialog.show();
}
};
But this way I get an error and a force close down...
What is the best method to do this?
For the task you are trying to implement:
dialog.show();
// do some work
dialog.dismiss();
Now, to implement above, there is concept of AsyncTask, the best way to implement Threading task, as its also known as Painless Threading in Android.
AsyncTask has 4 main methods:
onPreExecute() - Here you can show ProgressDialog or ProgressBar.
doInBackground() - Here you can do/implement background task
onProgressUpdate() - Here you can update UI based on the intermediate result you receive from webservice call or from background task
onPostExecute() - Here you can dismiss dialog or make progress bar invisible. Also you can do the task which want to do after receiving result from background task or webservice call.
For this kind of task mostly I recommend you to use the AsyncTask. Here is one good example of it which will help you.
And for this question as You are making UI related task and for that please use the UI thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
//Show or Hide your ProgressDialog
}
});
Try to use runOnUiThread of the Activity instead of using Thread.
Check the following code snippet.
runOnUiThread(new Runnable() {
public void run() {
dialog = new ProgressDialog(ctContext);
dialog.show();
}
}
});
I think this will help you.
I am targeting Android 4.0 and am communicating with a telemetry device using TCP/IP. Android 4.0 forces all networking to be done in a separate thread. First I open a socket, then I contact the device and download some information all from a separate thread. At this point I want to display a progress dialong to show the progress of downloading more detailed information. My problem is that I cannot show the progress dialog from anywhere but the main UI. But, I do not know when I have reached the point in the other thread where I am ready to display the progress dialog. Is there some way I can check for this from the main UI without tying up the system?
Use Handler, like that :
final int PROGRESS_BY = 1;
final Handler handler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
switch (msg.what)
{
case PROGRESS_BY :
progressBar.setProgress((Integer) msg.obj);
break;
}
}
};
Thread thread = new Thread()
{
#Override
public void run()
{
super.run();
// do something
Message msg = new Message();
msg.what = PROGRESS_BY;
msg.obj = new Integer(10);
handler.sendMessage(msg);
// do something
[...]
}
};
AsyncTask is framework provided utility that is meant for cases like you describe.
From the other thread, i.e the one in which the async task is executing, you can publish progress using publishProgress() method of AsyncTask. Its asynchronous and runs on a different thread but has event callbacks that run on main thread. OnProgressUpdate() is the method where you can work with a progress dialog.
http://developer.android.com/reference/android/os/AsyncTask.html
To trigger the dialog on your main ui, you need to use 'context.runOnUiThread()' where context is the reference to your display activity. It's also worth looking into using an AsyncTask.
Here is an android blog post that explains everything in detail: http://android-developers.blogspot.ca/2009/05/painless-threading.html
As an aside, you can also just start displaying a indeterminate progress dialog from the start, so the user is never waiting without visual feedback, then switch to the determinate when you know the download details.
onCreate(Bundle savedInstanceState){
// show dialog A if something is not correct
new Thread(){
public void run(){
if(something is wrong) {
runOnUIThread(new Runnable(){
public void run(){
showDialog(A);
}
});
}
}
}.start();
// show dialog B
showDialog(B);
}
I want to know
which dialog will be shown first, and is the order indeterminate? why?
if the order is indeterminate, how can i reproduce the case that A is shown before B?
Thanks!
Which dialog will be shown first is not defined and you should not rely on one occurring before the other as above. The thread scheduler is not identically deterministic in all situations.
You need to lock on a mutex (or any other locking device) to make sure one is shown before the other.
Your question about which dialog will show first is indeterminate. There are cases where the order will flip flop. But generally B would be shown first since 9/10 it will get to place it's event on the UI thread before your thread could detect there was a problem.
I'd suggest using AsyncTask to perform whatever mechanisms are needed to startup, then in the onPostExecute() allow your program to resume starting up so it can showDialog(B) for whatever it needs. That way if dialog A is showing you can stop the startup process there and not show b.
public class MyAsyncStartup extends AsyncTask<Integer,Integer,MyResult> {
MyActivity activity;
public MyResult handleBackground() {
if( somethingWentWrong ) return null;
}
public onPostExecute( MyResult result ) {
if( result == null ) {
showDialog(B);
} else {
activity.resumeStartupAndShowA();
}
}
}
I don't think it is possible that A is shown before B... this is because runOnUIThread adds the event TO THE END of the event queue. The code in that event (showing dialog A) is not going to get executed until after the onCreate() finishes (which means that dialog B gets shown first).
What cannot be guaranteed is the order between showing dialog B and calling runOnUIThread, but that doesn't matter. Here is a fragment from the official docs:
[runOnUIThread] 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.
N/A
You can't show B until you know whether or not A will be shown. So you have to wait for the worker thread no matter what. Would it be possible to put showDialog(B) in your other thread like this?
onCreate(Bundle savedInstanceState){
// show dialog A if something is not correct
new Thread(){
public void run(){
runOnUiThread(new Runnable(){
public void run(){
if(something is wrong) {
showDialog(A);
}
showDialog(B);
}
});
}
}
}.start();
}
Well I've seen a wide variety of failures while trying to get this to work. I have a thread that is started via an Activity. The thread needs to create/display progress dialogs and dismiss them.
When I tried to directly display the ProgressDialog I got an error that my Looper wasn't prepared. I looked up with a Looper was an implemented it. However, I had to call Looper.loop for the progress dialog to show up. After it showed up the application froze on that point never to continue past the Looper.loop call.
I couldn't get it to work so looked for a whole new way using a HandlerThread and a Handler. I create a HandlerThread and start it. I get the looper from the thread and create a Handler with it. My ProgressDialog or Toasts won't show up at all.
Is there an easier way to go about doing this?
U can have an
private Handler stopProgressHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
setProgressBarIndeterminateVisibility(false);
}
};
private Handler startProgressHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
setProgressBarIndeterminateVisibility(true);
}
};
so that when u start the thread start the progressbar and after thread is completed u can stop the progressbar.
public void closeProgressbar(){
//bluetoothconnector.onDestroy();
stopProgressHandler.sendEmptyMessage(0);
}
public void openProgressbar(){
//bluetoothconnector.onDestroy();
startProgressHandler.sendEmptyMessage(0);
}
This will help to call the progressbar to start and stop.. This will be one of the solution..
Not sure about ProgressDialog, but all UI related stuff in Android, as far as I know, required to be updated in UI Thread. There's actually an easy helper class for implementing async task: http://developer.android.com/reference/android/os/AsyncTask.html
Alternatively, you can create a Handler (which would be on UI Thread) and create the dialog using that:
Handler uiHandler;
//Activity onCreate
onCreate(...){
uiHandler = new Handler();
}
// Somewhere in your other thread,
uiHandler.postRunnable(new Runnable(){
#Override
public void run(){
// Create or update dialog
...
}
});
The last answer is wrong....
it should be:
setProgressBarIndeterminateVisibility(Boolean.TRUE | Boolean.FALSE);
I am now working on an android app in which I need to display a text after some processing is done.
I'm using a Thread to run a process in the back while my progress dialog is being displayed to the user. The Thread works properly and I've followed it step by step and, apparently, it also ends fine; however, the method in which I call it does not seem to come to an end (at least, during a normal cycle) because the text I am setting afterward does display immediately, I have to wait and do some other action (like in order for it to display
Below is the piece of code I'm having trouble with:
private OnClickListener saldoDisp = new OnClickListener(){
public void onClick(View v){
int x = s2.getSelectedItemPosition();
branchSel = arrSucsId[x];
mainProc();
saldoAdminTex.setText(strSaldo); //The late one
}
};
public void mainProc(){
chekP = new Thread (null,doProc,"Background");
chekP.start();
mProgress =ProgressDialog.show(SivetaAsaldo.this, "","Obteniendo saldo...",true, false);
}
private Runnable doProc = new Runnable(){
public void run(){
if(getSaldoAdmin(levelSel,branchSel))
{
mProgress.dismis();
Log.i(TAG,"Task completed properly");
}else
handler.post(tosti);
}
};
So I do get the "Task completed properly" but seems like it still waits for something else, any clues guys?
Thanks for taking a bit of your time to check it out =).
saldoAdminTex.setText(strSaldo); //The late one
is going to get called immediately. It doesn't wait until after the Thread started in mainProc ends. You also cannot dismiss the Progress Dialog in your runnable. You can only do UI related things on the main UI thread.
It would help you to read the article on Painless Threading on the Android Dev site.
About your ProgressDialog, please see this answer about how to use a AsyncTask with a ProgressDialog.
Looking at your code, this:
saldoAdminTex.setText(strSaldo);
would potentially be executed before your thread finishes as the thread will be running in parallel to that line.
An alternative way would be to do this:
public void mainProc(){
mProgress =ProgressDialog.show(SivetaAsaldo.this, "","Obteniendo saldo...",true,false);
handler.post(new Runable(){
public void run(){
if(getSaldoAdmin(levelSel,branchSel))
{
mProgress.dismis();
saldoAdminTex.setText(strSaldo);
Log.i(TAG,"Task completed properly");
}else
handler.post(tosti);
}
});
}