How to handle progress dialog correctly in android? - java

I am new in android and java. I am in a trouble in implementing progress dialog correctly.
I have a code like this
ProgressDialog dialog= new ProgressDialog(Main.this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMax(100);
dialog.show();
MY METHOD WHICH GRABS DATA FROM INTERNET;
dialog.dissmiss();
but by implementing this, my method runs well but no progress dialog is visible, again when i comment out the dismiss method, the dialog doesnt stop and i had to force close the app,then how to use this dialog? in aditional dont want to bring any thread here, is there any way to use dialog without any thread? Thanks

Problem here is that any long running tasks such as fetching data from the Internet must be run inside a separate thread, otherwise you're likely to get an ANR if your code runs for more then 5 seconds. The ideal solution in my opinion is to implement an AsyncTask: it lets you run tasks in a separate thread and helps you easily update your UI thread, showing ProgressDialogs or ProgressBars to let your users know that your app is currently busy. Simply place all your ProgressDialog initialization code inside the onPreExecute() method of the AsyncTask, and the dialog.dismiss() call to onPostExecute(). Hope this helps.

Yes, you no need to use Thread class. You can use AsyncTask instead. Start the progress dialog when you call the AsyncTask, dismiss it in the postExecute method.

I personally prefer AsyncTask for progress dialog.
In your onPreExecute, create your above code. In doInBackground, do your background tasks and in onPostExecute display an alertdialog saying work done !

Related

Activity not paused quickly enough

In my AppCompatActivity, I am showing an AlertDialog at a specific event.
Once the AlertDialog is shown, the user should not be able to click on anything in my AppCompatActivity anymore.
I tried to disable the activity in onPause(): getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
And to check whether it is not paused: getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)
But it seems that onPause() is not called quickly enough for that.
I could set a static boolean to true whenever I pause the AppCompatActivity, set it on false in onResume() and check it in every single onClickListener/onTouchListener etc., but is there a better way to do it?
Every help is appreciated!
Edit:
Thanks for your comments! I found out, that when I am clicking on the screen while the UI thread is started (for opening the AlertDialog), the click is put in a queue. That's why the click event is executed while the AlertDialog is running. Do I need to save the AlertDialog and check if it is running or is there a better way?
I believe that you should let us know more about your code. However, I think that I can guess what you're saying. There is a setEnabled(false) method for every view component in android, and if you call it on a view component java object, it'll be disabled and no longer clickable. So you can simply disable your components whenever you want to show the AlertDialog and then enable them again by calling setEnabled(true) if you wish. I'm pretty sure pausing the activity is not what you should do. Because doing it manually, is not best practice anyway, at all.
I ended up saving an instance and writing a method to check if the Activity should not be active:
private void canRun() {
return (dialog == null || !dialog.isShowing()) && getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED);
}

Call Dialog from function [Android Studio]

Did someone know how I can call a dialog from function and if it's possible, because I've already try and this is return to me :
W/System.err: java.lang.RuntimeException: Can't create handler inside thread Thread[AsyncTask #1,5,main] that has not called Looper.prepare()
Thanks by advance.
Somehow you are not calling Dialog from the main thread, can you post some code? Take a look here Showing dialog from background thread
Showing a dialog means updating the UI, but you can't do it from a background thread. Show the dialog in onPostExecute()

Is it safe to keep a callback listener in Activity like Dialog?

we know that, Dialog can hold a callback listener like OnCancelListener, when the dialog is canceled
the method of listener get callback. I want to know is it safe to keep a listener in Activity,just like the Dialog. For that, I can get callback when the Activity finish.
If it's not safe to do this, why?
Can somebody help me?
You Need onActivityResult() that is you need result from an activity you can use startActivity for result. refer this for more info.

Suspend Android app's main thread while showing the ProgressDialog

When my Android app is starting up needs to load a lot of data from the database during onCreate in the firstly loaded activity. I would like to show a ProgressDialog for that. ProgressDialog however can't be shown in the main thread, so one must use AsyncTask or new Thread. But that also means, that the activity continues to be initialized as the main thread goes on.
Basically, I need to show the ProgressDialog or a kind of its equivalent while processing in the main thread (not in AsyncTask).
Is there a way to do it?
ProgressDialog however can't be shown in the main thread, so one must use AsyncTask or new Thread.
How do you come to this conclusion? ALL UI stuff is shown in the UI Thread, thus also the ProgressDialog. It needs to be created and invoked inside the UI Thread to work or else your App crashes.
First you need to check on onCreate() if your stuff is already loaded and if not, show a ProgressDialog, load stuff in the background and then do a post in the UI Thread to dismiss the ProgressDialog and show the results.
That's how it usually works.
The Main/UI Thread is responsible for drawing the UI, and hence, the ProgressDialog itself . So you can not block it and hope that he is going to draw the UI. You should move the initialization stuff inside AsyncTask's doInBackgroud, and move on with the other suff after onPostExecuted is called
You should load the the data with the Thread (ASyncTask) you should display your ProgressDialog with "onPreExecute()" update it with "onProgressUpdate()" and finish the dialog with "onPostExecute()" all of them is running on UI thread already.
You will never be able to show progress because your view of activity have not created, because you read from database in onCreate methode after reading the database onCreate method finshes and now your view inflate and so on . . .

Progress dialog during tab switch

When the user switches from tab A to tab B it takes a long time (6 seconds), so I put in a progress dialog to let the user know that the app is working on it. The timeline is as follows:
Activity B onCreate - creates ProgressDialog and puts long tasks in a background Thread.
Activity B onStart
Activity B onResume
Activity B appears on the screen
This all works great with one "minor" snafu- the app intermittently crashes because the onResume function references something that is created by the background Thread. It is, in other words, a classic race condition.
To fix the race condition I did a "join" on the thread right before the reference in onResume, but that makes the progress dialog not show up until the background thread is done (i.e. it shows up for a split second and then goes away) and the app acts like it is hung while the background thread is working. Apparently the progress dialog cannot show up until onResume completes.
My question is this: how can I get the ProgressDialog to show up without crashing the program? Or do I need to either get the offending reference out of onResume or live with the app acting hung?
I ended up using a kludgey solution wherein the onResume function waits for the intermediate result that it needs, but not for the entire background thread to finish. This is ugly, I know, but it appears to work.
The better long term solution, I believe, is to separate the creation of the needed object from the long initialization steps that it does when it is created. The timeline would then be:
onCreate
Create object
Create progress dialog
Create background thread, have it do long initialization of object.
onStart
onResume (with no check/sleep loop).
A dirty solution would be to have one ProgressDialog for steps 1 and 2, and then create a second identical-looking one for steps 3 and 4.
Are you using Threading as provided by the Java platform or are you using the Android convenience classes?
I am referring to AsyncTask. More than likely you are running in to issues with your Runnables posting at inconvenient times. The AsyncTask class packages up these features nicely. Subclass AsyncTask, specifying the types for your params, progress, and result. Then hide your dialog in the onPostExecute method, while you perform background work in the doInBackground method.
Sample code:
AsyncTask<Void, Void, Void> parseTask = new AsyncTask<Void, Void, Void>() {
#Override
protected void onPostExecute(Void result) {
// Dismiss the progress dialog
dismissDialog(PROGRESS_DIALOG);
}
#Override
protected Void doInBackground(Void... params) {
// Do background work
return null;
}
};
// Start the background thread
parseTask.execute();
Taken from a live code base. Also don't feel too bad, concurrent programming is easily one of the more difficult systems to program. It is promising that you were able to recognize and identify the race condition.

Categories