There are a number of questions involving the lack of ability to dismiss a ProgressDialog, but none of them seem to cover my situation.
I have a Thread that runs a Runnable object that, when it completes, sends a message to a Handler object which I'm certain is sitting on the same thread as the ProgressDialog. The handler does this:
if(progressDialog != null){
Log.w(TAG, "Progress dialog is dismissed");
progressDialog.dismiss();
}else{
Log.w(TAG, "Progress dialog is null");
}
I've done this a million times before, and it's worked. The ProgressDialog goes away. But, in one particular instance, it doesn't.
In this particular case, a ProgressDialog (we'll call uploadChangesDialog) is showing, then a particular Handler (uploadChangesHandler) is called. After dismissing the uploadChangesDialog, it does a check that, if true, starts a different ProgressDialog (refreshViewDialog) and a Runnable (refreshViewRunnable) in a Thread. However, when it's Handler is called (refreshViewHandler), it can't close the dialog. But it does log Progress dialog is dismissed.
This is particularly strange, because the refreshViewsRunnable is run when the Activity is started, too, but it can get rid of the dialog then, just fine. The progressDialog variable above is the only one of it's kind, which is supposed to hold whatever ProgressDialog is currently showing.
I've done this with AlertDialogs before, but they know how to close themselves, so if I'm doing something wrong, then I wouldn't have noticed.
In the onCreateDialog() method:
case DIALOG_REFRESH_VIEW:
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading details...");
progressDialog.setCancelable(false);
return progressDialog;
Copied for each instance, with a different message. I did change it to all dialogs pointing to the same code, and setting the message in onPrepareDialog(), but that didn't change any behaviour.
In the UploadChangesRunnable:
public void run(){
int result = 0;
if(uploadChanges()){
result = 1;
}
uploadChangesHandler.sendEmptyMessage(result);
}
And then in uploadChangesHandler:
public void handleMessage(Message msg){
if(progressDialog != null){
progressDialog.dismiss();
}
if(msg.what == 0){
showDialog(DIALOG_UPLOAD_CHANGES_FAILED); //This is an AlertDialog
}else{
//All this does is showDialog(DIALOG_REFRESH_VIEW) then run the thread.
//This method is in the enclosing Activity class.
refreshViewInThread();
}
}
Finally, the refreshViewInThread method:
private void refreshViewInThread(){
showDialog(DIALOG_REFRESH_VIEW);
Thread thread = new Thread(new RefreshViewRunnable(refreshViewHandler));
thread.start();
}
And the RefreshViewRunnable looks remarkably similar to the UploadChangesRunnable.
There must be some special case that makes me lose the link to my progressDialog, and the dialog that I'm dismissing is likely not the dialog that is showing, but I can't think of how that could be. Any ideas?
my guess is that this is a context/handler issue. I had a similar problem, and decided to use interfaces/callbacks instead of Handler, and it fixed my problem.
However, you could try the following, where you see this: >> But it does log Progress dialog is dismissed.<< , add:
MyActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog.dismiss();
}
});
Related
I am working on a program that searches the users phone for some date, which takes about 2-3 seconds. While it's computing I want to display a loading screen, so the user knows something indeed is happening. However, when I try to display a loading screen before the computations, nothing is displayed on the screen.
This is what I have:
ProgressDialog loading= new ProgressDialog(this);
loading.setTitle("Loading");
loading.setMessage("Please wait...");
loading.show();
//search stuff
loading.dismiss();
In addition to this, I have tried putting the ProgressDialog in a thread like the following,
new Thread(new Runnable(){
public void run(){
ProgressDialog loading= new ProgressDialog(this);//error here for "this"
loading.setTitle("Loading");
loading.setMessage("Please wait...");
loading.show();
}
});
//search stuff
but it fails due to the "this" keyword, I believe because its referring to an Activity and not a regular class, but I could be wrong...
How can I get the ProgressDialog to display properly?
Try to handle it in this way
mProgressDialog = ProgressDialog.show(this, "Please wait","Long operation starts...", true);
new Thread() {
#Override
public void run() {
//Do long operation stuff here search stuff
try {
// code runs in a thread
runOnUiThread(new Runnable() {
#Override
public void run() {
mProgressDialog.dismiss();
}
});
} catch (final Exception ex) {
}
}
}.start();
Use async task for heavy task. Put your progress dialog code in onPreExecute method progress dialog dismiss code in onPostExecute method and all your heavy task in doInBackground method.
try passing down the context on a new class with your progress bar (this goes on your main activity)
NAME_OF_YOUR_CLASS context = new NAME_OF_YOUR_CLASS(getApplicationContext());
and on your class call the method like this..(this goes on class)
public Networking(Context c) {
this.context= c;
}
dont forget to make context a field (private final Context context;)
hope this helps
also idk if this will work but try to extend AsyncTask and use methods to run your progress bar there.
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...:-)
when does the progress dialog not show in android? i want to know the circumstances when the above can happen:
in my case the progress dialog was not showing in this case:
func{
progressdialog.show();
....
.....
anotherfunction();
listview.setAdapter();
progressdialog.dismiss();
}
what is the general rule of thumb with dialog boxes?
thank you in advance.
EDIT
when the .show() command is executed the progress dialog should show. But when the otherfucntion() is called, does the previous command of progressdialog show stop?
Seems like you need to use AsyncTask the UI (including the progressDialog) will not update if the UI thread is still busy. There are many examples in SO for that.
And as a rule of thumb - if you need Progress dialog - you need AsyncTask.
It is not that any command stops, it is just that if you execute a sequence of methods on the UI thread, the UI will probably not be updated until the sequence is over, which is after progressDialog.dismiss(), so the progressDialog should not be displayed anymore.
I think You have to do this in your activity.
ProgressDialog _progressDialog = ProgressDialog.show(this,"Saving Data","Please wait......");
settintAdater();
private void settingAdater(){
Thread _thread = new Thread(){
public void run() {
Message _msg = new Message();
_msg.what = 1;
// Do your task where you want to rerieve data to set in adapet
YourCalss.this._handle.sendMessage(_msg);
};
};
_thread.start();
}
Handler _handle = new Handler(){
public void handleMessage(Message msg) {
switch(msg.what){
case 1:
_progressDialog.dismiss();
listview.setAdapter();
}
}
}
To show a ProgressDialog use
ProgressDialog progressDialog = ProgressDialog.show(PrintMain.this, "",
"Uploading Document. Please wait...", true);
And when you have completed your task use
progressDialog.dismiss();
to dismiss the ProgressDialog ..
You can call to show the ProgressDialog in your onPreExecute method of AsyncTask class and when your done dismiss it in the onPostExecute method
I'm using a standard ProgressDialog implementation: I set up a thread to run a long task, and when it's done it dismisses the ProgressDialog.
#Override
public void onCreate( Bundle bundle ) {
super.onCreate( bundle );
context = this;
progress = ProgressDialog.show( this, "Running", "Please wait..", true, false);
progress.setOnDismissListener( new OnDismissListener() {
public void onDismiss(DialogInterface dialog) {
showResults();
}
});
new DeleteThread().start();
}
And the Thread looks like this:
private class DeleteThread extends Thread {
public DeleteThread() {}
#Override
public void run() {
// long process during which we populate
// a LinearLayout with many other Views
progress.dismiss();
}
}
And in showResults() we take the LinearLayout now filled with Views and set it as the content of an AlertDialog.
The problem is, the ProgressDialog goes away and there's still a long period of time (10-12sec) where nothing is happening before the AlertDialog pops up. Is there a way to make this transition instantaneously?
I know this answer might be coming in a bit late, but what the heck.
I see that you're triggering the showResults() method from the onDismiss callback. I would suggest you do it the other way around. To do that you may need to use the AsyncTask class.
The AsyncTask allows you to easily setup tasks to run in a spawned thread, to update a progress bar if needed (not required, but might be a nice touch in your case) and of course to run some code on the UI thread once the spawned thread completes. For your case, I would place your populating of layoutview in the AsyncTask.doInBackground() method. Then, you'd want to add the showResults() method call in AsyncTask.onPostExecute(). At the bottom of onPostExecute() you should then dismiss your progress dialog. That SHOULD give you the results you want.
As a bonus, you might want to create a constructor for your AsyncTask class and place the creation of the ProgressDialog in there. That way the ProgressDialog will be completely encapsulated within that class and everything is nice and clean. So, something like this:
class MyAsyncClass extends AsyncClass
{
ProgressDialog m_progress;
public MyAsyncClass()
{
m_progress = ProgressDialog.show( this, "Running", "Please wait..", true, false);
}
protected Long doInBackground(Object... data) {
// Do your long process of populating a LinearLayout with many other Views
}
protected void onPostExecute(Long result) {
showResults();
m_progress.dismiss();
}
}
NOTE: Above needs some extra parameters to the class, but you get the idea.
I'm going to venture a guess as a novice Android developer and suggest that while the pointers are generated for the LinearLayout, the layout itself hasn't been populated with content and therefor is populating when you call progress.dismiss()
You will probably have to render the view prior to setting to the AlertDialogs content. http://developer.android.com/guide/topics/ui/how-android-draws.html might have some help in that respect, unfortunately my laptop is have HDD issues so I don't have the Android Development Environment installed and can't try it. But I'd try an invalidate on the LinearLayout right before progress.dismiss(), I hope that helps :S
Make use of something like this below and use an AsyncTask that dismisses the dialog once it is done:
final ProgressDialog progressDialog = new ProgressDialog(v.getContext());
progressDialog.setCancelable(false);
progressDialog.setMessage(v.getContext().getText(R.string.defaultQuantities));
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMax(100);
new CountDownTimer(250, 250) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
if (progressDialog.getProgress() < 100) {
progressDialog.show();
}
}
}.start();
I'm trying to create a ProgressDialog for an Android-App (just a simple one showing the user that stuff is happening, no buttons or anything) but I can't get it right. I've been through forums and tutorials as well as the Sample-Code that comes with the SDK, but to no avail.
This is what I got:
btnSubmit.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
(...)
ProgressDialog pd = new ProgressDialog(MyApp.this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("Working...");
pd.setIndeterminate(true);
pd.setCancelable(false);
// now fetch the results
(...long time calculations here...)
// remove progress dialog
pd.dismiss();
I've also tried adding pd.show(); and messed around with the parameter in new ProgressDialog resulting in nothing at all (except errors that the chosen parameter won't work), meaning: the ProgressDialog won't ever show up. The app just keeps running as if I never added the dialog.
I don't know if I'm creating the dialog at the right place, I moved it around a bit but that, too, didnt't help. Maybe I'm in the wrong context? The above code is inside private ViewGroup _createInputForm() in MyApp.
Any hint is appreciated,
you have to call pd.show before the long calculation starts and then the calculation has to run in a separate thread. A soon as this thread is finished, you have to call pd.dismiss() to close the prgoress dialog.
here you can see an example:
the progressdialog is created and displayed and a thread is called to run a heavy calculation:
#Override
public void onClick(View v) {
pd = ProgressDialog.show(lexs, "Search", "Searching...", true, false);
Search search = new Search( ... );
SearchThread searchThread = new SearchThread(search);
searchThread.start();
}
and here the thread:
private class SearchThread extends Thread {
private Search search;
public SearchThread(Search search) {
this.search = search;
}
#Override
public void run() {
search.search();
handler.sendEmptyMessage(0);
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
displaySearchResults(search);
pd.dismiss();
}
};
}
I am giving you a solution for it,
try this...
First define the Progress Dialog in the Activity before onCreate() method
private ProgressDialog progressDialog;
Now in the onCreate method you might have the Any button click on which you will change the Activity on any action. Just set the Progress Bar there.
progressDialog = ProgressDialog.show(FoodDriveModule.this, "", "Loading...");
Now use thread to handle the Progress Bar to Display and hide
new Thread()
{
public void run()
{
try
{
sleep(1500);
// do the background process or any work that takes time to see progress dialog
}
catch (Exception e)
{
Log.e("tag",e.getMessage());
}
// dismiss the progress dialog
progressDialog.dismiss();
}
}.start();
That is all!
Progress Dialog doesn't show because you have to use a separated thread. The best practices in Android is to use AsyncTask ( highly recommended ).
See also this answer.
This is also possible by using AsyncTask. This class creates a thread for you. You should subclass it and fill in the doInBackground(...) method.