Android - closing progress dialog from event handler - android

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.

Related

Indeterminate Progress Bar only shows very briefly at the end of the operation

I want it to show up as soon as I click the login button, but it only shows after the loggin process has finished
What am i doing wrong
runOnUiThread(new Runnable() {
public void run() {
mProgress.setVisibility(View.VISIBLE);
}
});
doLogin();
mProgress.setVisibility(View.INVISIBLE);
Since you are using another thread to show the Visibility, the runnable might get scheduled any time in the future. That is the reason it is being shown late.
Maybe adding a sleep routine in current thread immediately after runonuithread call might schedule the runnable, but you can never be really sure.
Edit: Or you could create a Handler which shows Progress bar and wait for it to be shown and then continue
The reason You don't see the loading dialog is that you call a blocking function in your GUI thread/MAIN thread.When you set your dialog to visible you should let the GUI thread to keep running so it can draw the dialog on the screen.Moreover after 5 seconds that the GUI thread is blocked, the user will be presented with FORCE CLOSE/Wait pop up.
It is a bad practice to preform long operation of the gui thread, you MUST only can non blocking function in it.
Here is how you should do it:
//make sure mProgress is final
mProgress.setVisibility(View.VISIBLE);
new Thread(){
public void run(){
doLogin();
mProgress.setVisibility(View.INVISIBLE);
}
}.start();

Android - show progress dialog while doing work on UI thread

I need to do some work on the UI thread, specifically setting up some views, etc. - this can't be done in a background thread. The process is invoked on a button click and takes about a second or so to complete - without a progress dialog it looks as if the app is frozen. I use progress dialog with AsynTasks in several places and it works fine - however here I'm struggling.
I started with simple:
showDialog(DIALOG_PLEASE_WAIT);
viewInfo.setFromGuide(true); //this method just sets a variable
viewInfo.setVenue(venue); //this method does a lot of UI manipulation and takes a second or so
showScreen(VIEW_INFO); //this method shows the corresponding view in ViewFlipper
dismissDialog(DIALOG_PLEASE_WAIT);
However the dialog would not show (sort of expected, as this is all on UI thread.
Then I changed the code to this:
Handler hnd = new Handler() {
#Override
handleMessage(Message m) {
viewInfo.setFromGuide(true);
viewInfo.setVenue(venue);
showScreen(VIEW_INFO);
dismissDialog(DIALOG_PLEASE_WAIT);
}
}
showDialog(DIALOG_PLEASE_WAIT);
new Thread() {
public void run() {
hnd.sendEmptyMessage(0);
}
}.start();
This still doesn't show the dialog - naturally, the UI work in handleMessage is still done on the UI thread. So, what can I do to show the progress dialog?
If it takes really takes a second or so to complete than maybe you can just use a simple Toast notification with a message like "Please wait"
as you are using AsyncTask you can override onProgressUpdate which is called when ever you call publishProgress() from inside the doInBackGround so you can publish your results smoothly while working in background because, onProgressUpdate works on the UI thread.

Android - Starting a thread crashes app

I've got a few activities. In the main activity I have a login screen, when the user presses the login button, a thread is started to show a progress dialog until the user has been authenticated. At this point i load the next activity which has several fields for the user to input data.
Here the user inputs some data and presses a button to process it. The data is passed to a new activity where the data is actually processed and displayed. This is where i create the new thread and where it's crashing when i call thread.start(); and I have no idea why this is happening.
Both activities are implementing Runnable.
I'm using the same code below to create and call thread.start() in the button press of the first activity and the onCreate method of the last one:
pd = ProgressDialog.show(search_results.this, "", "Searching...", true, false);
Thread thread = new Thread(this);
thread.start();
I'm using the same code below as well to handle the threads for both as well.
public void run() {
handler.sendEmptyMessage(0);
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
pd.dismiss();
}
};
Am I missing something? I don't really understand why it's crashing.
While I encourage people to use AsyncTask, it's not really needed, especially for simple things like progress/loading dialogs. That's not the problem here.
Your question and your code is confusing. I'm not sure which code goes where, on which activity, and I hope you're not leaving dialogs open between activities, trying to access them across them (it won't work, of course). Also, providing a Context to a Thread does not even compile (it's marked with errors at design time). To sum it all up, you didn't provide the Log entry. Sorry, I can't make sense of what you're doing or where the error is. We can only guess.
Below are one of the possible ways to do it with a Handler, a Runnable and a Thread. This was taken from the Developer Resource when I first learn how to use it:
1- You declare a Handler. Most people do this on the onCreate section to reuse it often:
Handler mHandler = new Handler();
2- When you need, you start a Thread:
new Thread() { public void run() {
mHandler.post(mLoadingData);
// ... do work
mHandler.post(mLoadingDataStop);
}}.start()
3- These are the Runnables that are posted to the Handler:
private final Runnable mLoadingData = new Runnable() {public void run() {
showDialog(LOADING_DIALOG); // In your case, show your custom dialog
}};
private final Runnable mLoadingDataStop = new Runnable() {public void run() {
dismissDialog(LOADING_DIALOG); // In your case, dismiss the dialog
}};
For a progress dialog, things need a bit more work (update the progress etc.), but for a loading dialog, you don't need to really mess with messages.
I had this same issue when developing for the tablet. After a certain API, I'm thinking 3.0 (sdk 11), Android enforces applications to run long running processes on a separate thread, otherwise it kills it. Logcat will confirm this.
I know you are using another thread, but that didn't work for me either. Try using AsyncTask. You can create a quick inner class that, in my opinion, is way easier than handling your own threads. AsyncTask has several functions that run on the UI thread and a couple that run on their own thread. This allows you to start a "Loading" user interface object on the user interface thread, process on the back end thread, and then when its done, it'll notify a user interface thread function.
You'll want to specifically look at override
onPreExecute()
doInBackground()
onPostExecute()

Progress Dialog Box Won't appear - Android

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!

Android Memory Leak: Multiple instances of activity in multiple threads

I need a "Loading" progressdialog to appear at the start of an activity, and then display some stuff after loading is finished. In my onresume, I have code similar to this:
loadThread = true;
Thread showDetailsThread = new Thread() {
#Override
public void run() {
while (loadThread == true) {
Looper.prepare();
try {
dialog = ProgressDialog.show(myactivity.this, "", "Loading data...", true);
} finally {
handler.sendEmptyMessage(0);
}
Looper.loop();
}
}}; showDetailsThread.start();
The handler (not shown) displays everything I need displayed, and while the data is loading, the progressdialog displays as expected. The problem is, after running the memory analyzer in eclipse, I realized that every time I visit this activity it spawns a new instance of everything created by the handler in a new thread, without destroying the previous one. With multiple instances of the activity running forever in multiple threads, I eventually run out of memory.
Here's what I don't understand. I was under the impression that, given the above example, the handler would run in the main ui thread, not in the new thread containing the dialog. The only thing that should exist in the new thread is the progressdialog, and the dialog is instantly dismissed at the beginning of the handler (not shown), which should stop the thread, right? Why are these threads being created and running indefinitely? BTW, I have "loadThread = false;" in my onpause, ondestroy, and onstop in an attempt to halt the thread after navigating to another activity, but it doesn't work.
If I just call the handler directly instead of running it in the showdetailsThread finally{}, everything is fine and there is no leak, but I really need the progressdialog to appear during the 2 second delay that occurs during loading.
There is probably a better way to do this anyway. Any help is greatly appreciated.
No more memory leak now. I needed to create a handler within the new thread, which would bind to the Looper (somewhere between Looper.prepare() and Looper.loop():
threadKillerHandler = new Handler();
And then call quit() on the looper's handler when I'm done with the thread (in onDestroy in my case):
threadKillerHandler.getLooper().quit();
Otherwise the thread will run forever, and instances will keep piling up every time a user revisits the activity.
I would suggest using AsynchTask instead of the way you are doing it. This will precent the multiple instances appearing.
Documentation
Example

Categories

Resources