I'm having a small problem handeling ProgressDialog and the suer hitting the home key.
I create my ProgressDialog as follows:
runOnUiThread(new Runnable() {
public void run() {
progressDialog = ProgressDialog.show(this, "",this.getResources().getString( R.string.AProgressMessage), true);
}
});
and dismiss it when I finished downloading stuff of internet.
progressDialog.dismiss();
the problem is when a user hit the home key, sometimes the Thread that calls the dismiss is kille but hte dialog never gets dismissed... therefore when the app relaunches it gets stuck behind a ProgressDialog.
Any ideas ?
I know this thread is quite old, but I think my answer could help many people.
Activity class has an onPause method. So if you call the dialog from the same activity that is being paused, you can use the onPause method to dimiss the dialog.
Make the dialog variable global, and define the onPause method as follows:
#Override
public void onPause(){
super.onPause();
if(dialog!=null)
dialog.dismiss();
}
Why would the Thread be killed?
If the Android system thinks that the memory is low, it will only kill whole processes and not individual threads. Are you sure you always call progressDialog.dismiss(), even if the thread stops because of an uncaught exception (for example)?
By the way, you should probably use AsyncTask instead of doing the thread management yourself, see here.
Related
I have a web service request in my Android app which might take a second or two to run. I have an event handler which fires when it completes. I am trying to show a dialog to show the progress of this request.
So far I have this:
var progressDialog = Android.App.ProgressDialog.Show(this.Activity, "Please wait...", "Communicating with server...", true);
new Thread(new ThreadStart(delegate {
WCFClient WCF = WCFService();
WCF.TestCompleted+= TestCompleted;
WCF.TestAsync(GetID());
progressDialog.Dismiss();}
)
).Start();
The problem is obvious, the dialog displays and disappears in a flash. I am declaring var progressDialog in the UI thread. How can I reference it again in an event handler?
I would normally use RunOnUIThread but I cannot target "progressDialog" that way as it does not exist in my layout.
It seems like this should be easy - am I missing something in my approach?
There are a few issues with your code. The first is there is a memory leak. You are holding onto the progress dialog in your thread. If the user rotates the device, your Activity will be killed but the garbage collector won't be able to garbage collect the reference because your Thread is holding onto it.
Secondly, you cannot update the UI from another thread, you have to update on the UI thread.
You need to use a Handler, pass a reference to the other threads (in the constructor), then when needed send a message to UIthread to dismiss the progress dialog.
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
if (progressDialog.isShowing()) progressDialog.dismiss();
}
};
in the thread, do this:
mHandler.obtainMessage().sendToTarget();
Also there is another issue in the code, you don't seem to check if you completed the task, BEFORE dismissing the dialog.
I want to know what is the best way to stop an async task frm running.
I have tried
#Override protected void onCancelled() {
super.onCancelled();
mTask.cancel(true);
}
I also tried
asyncTaskObject.cancel(true);
This works specially when associated with an event.
But suppose the scenario is--- there are 4 AsyncTask. First call the second, second calls the third and third calls fourth. When the user enters the activity there is no dialogbox.
Otherwise we could have used the onCancel method there.
When user clicks on anywhere on the page the dialog box appears if user does not click anywhere then no dialog box is shown but async task keep running in the background.Suppose the user clicks the "back" button on or the navigational icon to the home page user.is taken out of the current activity. But the async task keep running in the background and eventually the app crashes. I have used to the cancel method in onBackPressed. But the problem is you cannot be sure which task is running and app carshes again.
What is the way out of this?
keep reference to AsyncTask object as instance variable and then in onDestroy() do this
#Override
protected void onDestroy() {
if (mTask != null) {
mTask.cancel(true);
}
super.onDestroy();
}
In http://developer.android.com/reference/android/os/AsyncTask.html there's a session called Threading rules that say that AsyncTasks instances must be created on the UI thread and execute must be invoked on the UI thread. If you invoke execute from the UI thread you can cancel the thread calling yourTaskInstance.cancel(true);
I am not entirely sure when you want to cancel your tasks, but here are a few suggestions: a) keep a reference to each task that is running. b) add a dismiss listener to your dialog and cancel all tasks there (if that's what you want to do). c) cancel all tasks at the onStop callback of your activity (if that's what you want to do again).
I have a few Activities on my app that hit a web service. Since I don't want to hold up the main thread, this code is in an AsyncTask. However, I do not want the user to be manipulating the Activity while the web service is being called, so before executing the AsyncTask I show a ProgressDialog which spins and blocks the screen. In the onPostExecute method of the AsyncTask, the first thing I do is dismiss the ProgressDialog.
This should prevent the user from manipulating the Activity without actually blocking the main thread.
However, I've noticed a few times where the ProgressDialog is never dismissed and the user becomes stuck. The AsyncTask has finished, onPostExcute has executed, but the ProgressDialog is still shown. The ProgressDialog has no chance of ever being dismissed and the user is stuck on the screen. Their only option is to visit the Android Settings app and force stop my application.
Does anyone have any idea why this happens? What can I do to fix it?
Relevant code:
This is how I show the ProgressDialog and launch the task:
mProgress = ProgressDialog.show(this, "", "Syncing...", true);
(new MyAsyncTask()).execute(intUserId);
This is the onPostExcute for the task. There is no "#Override"
protected void onPostExecute(Boolean result) {
if (mProgress != null) {
mProgress.dismiss();
mProgress = null;
}
}
Check this:
Make sure you called asynctack.execute() on UI thread.
Use #Override on onPostExcute() to make sure it's properly defined.
Maybe try showing your ProgressDialog in the onPreExecute() Method?
protected void onPreExecute() {
mProgress = ProgressDialog.show(this, "", "Syncing...", true);
}
Give that a shot and see if it works.
Peter Knego posted the following link in a comment under the OP. CommonsWare's solution seems to work well.
Backround task, progress dialog, orientation change - is there any 100% working solution?
I want to make a Progress Dialog Box in my app to use when sending some information. But the code I wrote won't work. It the method send() executes but the dialog box never appears because it dismisses very quickly
Here is my code :
ProgressDialog myProgressDialog = ProgressDialog.show(Tents.this,
"Please wait...", "Sending...", true);
send();
myProgressDialog.dismiss();
goFour();
How do I make the Dialog Box Last a little longer?
First of all - you should not do send() in the same thread as show() and dismiss() - because you are effectively blocking UI thread during sending. The dialog will actually never show - because in order to show it after show() is called, you need to give the control back to the main looper in UI thread and simply finish handling whatever event you are handling. Otherwise the UI thread will never have a chance to draw your dialog.
The best idea is to start running send() in AsyncTask and call dismiss() in onPostExecute() (see http://developer.android.com/reference/android/os/AsyncTask.html to get idea how to run async task).
You are probably getting a progress dialog, but having it immediately dismiss as it has nothing to wait for.
I'll pretend you want this in OnCreate for my example:
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ProgressDialog pd = ProgressDialog.show(this, "Please wait...", "Sending...");
new Thread(new Runnable(){
public void run() {
send();
pd.dismiss();
}
}).start();
gofour();
}
EDIT: If it still goes away immediately, make sure send(); does something that actually takes some time. ;)
The UI thread is used to start send() , this will not work and progress dialog will not be shown .
Call send in another thread or AsynTask doBackground and on completion dismiss the dialog.
If your send action is completing so quickly that the dialog is not displaying properly, might I suggest instead using an indeterminate progress bar in the upper right corner of your activity via requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS) and then utilizing setProgressBarIndeterminateVisibility(true/false).
"I guess my real question would then be how do I make it so that it lasts a little longer?" My answer would be WHY???!!!
I think you would be better showing an alert dialog to confirm your send function has completed, it would be annoying for the user having to wait for no reason!
I am developing my first Androïd application and I'm facing a problem when I want to display a ProgressDialog to indicate that a process is being run.
In my application, the user triggers a time consuming task by pressing a Button. The "OnClick" function of my "OnClickListener" is called when the user presses the Button. In this function, here is what I'm currently doing :
- creation and configuration of an instance of the ProgressDialog class,
- creation of a thread dedicated to the time consuming task,
- attempt to display the ProgressDialog using the "show" method,
- start of the thread,
- main Activity suspended (call of the "wait" function)
- wake up of the main Activity by the thread when it is finished
- removal of the ProgressDialog by calling the "dismiss" function.
Everything works fine (the result of the long task is correct) but the ProgressDialog nevers appears. What am I doing wrong?
Thanks in advance for the time you will spend trying to help me.
You should not call wait() to the Main Activity/UI thread, because this is actually freezing the UI including your ProgressDialog, so it has no time to fade in and will never be shown.
Try to use multithreading correctly: http://developer.android.com/resources/articles/painless-threading.html
final Handler transThreadHandler = new Handler();
public void onClick(View v) {
// show ProgressDialog...
new Thread(){
public void run(){
// your second thread
doLargeStuffHere();
transThreadHandler.post(new Runnable(){public void run(){
// back in UI thread
// close ProgressDialog...
}});
}
}.start();
}
I would suggest using AsyncTask, as it's purpose is exactly to handle this kind of problem. See here for instructions how to use it. Note that the linked page in Floern's answer also recommends the use of AsyncTask.
You would need to do the following:
subclass AsyncTask
override it's onPreExecute() method to create and show a ProgressDialog. (You could hold a reference to it in a member of your subclass)
override it's doInBackground() method to execute your time consuming action.
override it's onPostExecute() method to hide your dialog.
in your activity, create an instance of your subclass and call execute() on it.
If you make your subclass an inner class of your activity, you can even use all of your activity's members.