I am using an AsyncTask to handle complex background operations (compiling a log file to send) and I use a ProgressDialog to show the user progress. I have tried using showDialog() but it never seems to show or dismiss (it is never called), and I followed tutorials on how to do it...
So I am using unmanaged ones, and it won't dismiss my message. I am also wanting to update the message as it starts to compile the log file (as it seems to lag there - or maybe the text view is just really long so it doesn't update like it is supposed to).
I have moved my code around a bit so it look like there are problems (like onProgressUpdate()), but I don't know how to make it work. I have looked around this site and nothing seems to be having the problem I am (not exactly anyways). RunOnUiThread() doesn't work, new Thread(){} doesn't work, and onProgressUpdate() I can't get to work (the documentation is confusing on this).
It also never dismisses. I have set up a listener and it never dismisses.
Does anyone know what is wrong with my code? I thought AsyncTask was supposed to be simple.
private class BuildLogTask extends AsyncTask<Void, Void, String> {
String temp;
ProgressDialog progressdialog = new ProgressDialog(context); //variable is defined at onCreate (held as private, not static)
#Override
protected String doInBackground(Void... params) {
temp = buildLog();
logdata = temp;
publishProgress();
createLogFile();
return temp;
}
protected void onProgressUpdate() {
progressdialog.setMessage("Compiling Log File...");
}
#Override
protected void onPreExecute() {
Log.w(TAG,"Showing Dialog");
send.setEnabled(false);
ProgressDialog progressdialog = new ProgressDialog(context);
progressdialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressdialog.setMessage("Gathering Data...");
progressdialog.setCancelable(false);
progressdialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
Log.e(TAG,"Progress Dialog dismissal.");
}
});
progressdialog.show();
}
#Override
protected void onCancelled(){
Log.e(TAG,"Progress Dialog was Cancelled");
progressdialog.dismiss();
logdata=null;
}
#Override
protected void onPostExecute(String result) {
progressdialog.dismiss();
send.setEnabled(true);
previewAndSend();
}
}
You have two different progress dialogs there, one local to onPreExecute() and one global. The one ur dismissing in your onPostExecution() is your global one which was never actually shown. Remove the local declaration and it should work.
There are two problems.
The signature for on onProgressUpdate is not correct. Try this instead:
#Override
protected void onProgressUpdate(Void... progress) {
progressdialog.setMessage("Compiling Log File...");
}
You're masking the progressDialog member variable with a local variable in onPreExecute()
EDIT: Second problem identified:
Try it,
Replace:
progressdialog.show();
For:
progressdialog = progressdialog.show();
Good luck.
Related
i'm trying to add a indeterminate progressDialog to my UI once i click a list element that calls a AsyncTask, but unfortunately, if I call the dialog on the onPreExecute like this:
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog.setProgressStyle(R.style.AppTheme_Dark_Dialog);
dialog.setIndeterminate(true);
dialog.setMessage(activity.getString(R.string.Buscando));
dialog.show();
}
Obs: Worth noting that the Async is not a subClass of the Activity Class, i'm passing the activity as a parameter to the constructor.
and
#Override
protected void onPostExecute(BuscaPendentesFechamento buscaPendentesFechamento) {
super.onPostExecute(buscaPendentesFechamento);
if(dialog.isShowing())
dialog.dismiss();
}
the dialog simply doesn't show at all, although it is created and called(alredy checked, the activity instance is correct)
and if I set the dialog on the activity itself, like:
final ProgressDialog progressDialog = new ProgressDialog(RegistraPeso.this, R.style.AppTheme_Dark_Dialog);
progressDialog.setIndeterminate(true);
progressDialog.setMessage(getString(R.string.Buscando));
progressDialog.show();
BuscaPendentesFechamento exportProjectRequisition = new BuscaPendentesFechamento(getApplicationContext());
response = exportProjectRequisition.execute(nomeEquip,RegistraPeso.this);
progressDialog.dismiss();
the Dialog shows on the Ui, but only after the AsyncTask alredy performed, and not before it is called, and according to the code, it should be showing before the Async even gets created.
What can I do? What am I doing wrong? Please help.
Edit: Added where the Dialog is created:
private ProgressDialog dialog;
private RegistraPeso activity;
BuscaPendentesFechamento(RegistraPeso activity) {
this.dialog = new ProgressDialog(activity);
this.activity = activity;
}
Edit: Added the doInBackground:
#Override
protected BuscaPendentesFechamento doInBackground(String... params) {
ArrayList<UmData> jsonArrayResponse = JSONParser.makeHttpRequestArray(
Constants.URL_PENDENTES_FECHAMENTO,
Constants.METHOD_POST, requisition.writeJSON(params[0]),
requisition.getContext());
if(jsonArrayResponse!=null)
requisition.setJsonArrayResponse(jsonArrayResponse);
else {
UmData umData = new UmData();
umData.setItemUm("Server not responding");
jsonArrayResponse = new ArrayList<>();
jsonArrayResponse.add(umData);
requisition.setJsonArrayResponse(jsonArrayResponse);
}
return requisition;
}
Application context would not work in this case . Replace line below
BuscaPendentesFechamento exportProjectRequisition = new BuscaPendentesFechamento(getApplicationContext());
To
BuscaPendentesFechamento exportProjectRequisition = new BuscaPendentesFechamento(YourActivity.this);
I see your code you are calling dismiss() just after execute(). Remove this line.
progressDialog.dismiss();
OP here, the problem was solved by changing the code based on [this][1]
[1]: How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class? post here, sent to me by #MikeM, The problem was that I was getting the response using the .get() from the AsyncTask, and it was transforming the Async into a Syncronous Task.
Thanks for the support Mike!
My onStart() event looks like this:
protected void onStart() {
super.onStart();
ShowProgressDialog();
Function1(); //this takes a lot of time to compute
HideProgressDialog();
Function2(); //this function uses the values calculated from Function1
}
But the ProgressDialog wont show.
PS: AsyncTask is not a good solution for my problem because Function2 needs the values calculated from Function1 and I really dont want to chain 4-5 AsyncTasks.
Write the following code onstart
pDialog = new ProgressDialog(this);
pDialog.setMax(5);
pDialog.setMessage("Loading...");
pDialog.setCancelable(true);
pDialog.show();
Seems the activity is not on top of the activtiy stack yet. As can be read in the documentation:
http://developer.android.com/reference/android/app/Activity.html
Also if you do have processing it can block the UI Thread. I would suggest to put it in A A-Sync task. In the asynctask the order is still top to bottom so no need to create multiply a-synctask.
Do this to show the dialog box:
private ProgressDialog inProgressDialog = new ProgressDialog(this);
inProgressDialog.setMessage("In progress...");
inProgressDialog.show();
and to stop dialog:
inProgressDialog.dismiss();
And I think in your case you can give call to function2 using Async task and pass it as params.
You need to run Function1 and Function2 in a background thread. The ProgressDialog will only show once all of OnStart() has finished. So, you need to thread the time consuming code to free up the UI, otherwise the progress dialog won't show.
This is always good practice in Android, if you run time consuming stuff on the main thread the operating system will pester the user with messages about the app being unresponsive.
Some pseudo code:
OnStart()
{
ShowProgressDialog();
StartTimeConsumingThread();
}
Then, in the time consuming thread:
TimeConsumingThread()
{
Function1();
Function2();
RunOnUiThread(
CloseProogressDialog();
)
}
I think for long time calculation it is better to use AsyncTask.
You can do something like this:
private class Task extends AsyncTask<Void, Void, Void> {
ProgressDialog pd;
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(MyActivity.this);
pd.show();
}
#Override
protected Void doInBackground(Void... params) {
Function1();
runOnUiThread(new Runnable() {
#Override
public void run() {
pd.dismiss();
}
});
Function2();
return null;
}
}
I'm trying to develop an application to understand android, application delete's default browser's history. Every thing is working fine, I'm using AsyncTask to accomplish the task with ProgressDialog
Here is how I'm deleting the History
ProgressDialog pd;
new AsyncTask<Void, Void, Void>()
{
#Override
protected void onPreExecute()
{
pd = ProgressDialog.show(HistoryClean.this, "Loading..",
"Please Wait", true, false);
}//End of onPreExecute method
#Override
protected Void doInBackground(Void... params)
{
Browser.clearHistory(getContentResolver());
return null;
}//End of doInBackground method
#Override
protected void onPostExecute(Void result)
{
pd.dismiss();
}//End of onPostExecute method
}.execute((Void[]) null);//End of AsyncTask anonymous class
But instead of ProgressDialog I want to implement CircularProgress which it can display the progress value like 10% , 90%....
Some times History may gets deleted faster and some times it may be slow, how to address this problem and dynamically update the CircularProgress bar with Progression Values.
Thanks in advance.
The best two library i found on the net are on github
https://github.com/Todd-Davies/ProgressWheel
https://github.com/f2prateek/progressbutton?source=c
Hope that will help you
AsyncTask has method onProgressUpdate(Progress... values) that you can call each iteration for example or each time a progress is done during doInBackground() by calling publishProgress(Progress...).
Refer to the docs for more details
I have an application that loads a dialog with some images specified in the dialog's XML layout. I've read a lot about using images in Android and being careful with the VM budget so I believe that any handling of images with the potential to take up a decent amount of memory should be handled off of the main thread. With that said I was wondering if it is wise to load an entire layout off of the UI thread using an ASyncTask. I have a working code but I couldn't find out if this was good practice through some Google searches. Here is the code below.
This is the case statement that triggers when the user presses a button to load the dialog.
case R.id.showDialog:
vibrator.vibrate(vibrateMilis);
mDialog = new Dialog(getActivity(), R.style.CustomDialog);
new LoadLayout().execute("");
break;
And here is the ASyncTask
private class LoadLayout extends AsyncTask<String, Void, String>
{
ProgressDialog progressDialog;
#Override
protected String doInBackground(String... params)
{
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
mDialog.setContentView(R.layout.dialog_layout);
mDialog.setCancelable(true);
return null;
}
#Override
protected void onPostExecute(String result)
{
progressDialog.cancel();
mDialog.show();
}
#Override
protected void onPreExecute()
{
progressDialog = new ProgressDialog(
getActivity());
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected void onProgressUpdate(Void... values)
{
// Do nothing
}
}
So this code works but the question I have is this. Is this considered good practice? It seems a bit hacky for my taste. I didn't come across this with multiple Google searches so that's why I'm a bit concerned. I mean if it was good practice it would've been documented somewhere right?
Thanks for any input.
Have you refer the android developer site. your approach is wrong. For more guidance please refer Vogella Documentation. Its a nice explaination of AsyncTask.
Also refer below example code for the AsyncTask.
// The definition of our task class
private class PostTask extends AsyncTask<String, Integer, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
displayProgressBar("Downloading...");
}
#Override
protected String doInBackground(String... params) {
String url=params[0];
// Dummy code
for (int i = 0; i <= 100; i += 5) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return "All Done!";
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
updateProgressBar(values[0]);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
dismissProgressBar();
}
}
Hope it will help you a lot.
Enjoy Coding... :)
I think you are doing it in a wrong way , because :
First,when call method doInBackground() , It will in other thread , you can only change UI elements in main thread .
Second,show a dialog is not waste time,you can call it in onPreExecute() or onPostExecute(String result),and just do actions in doInBackground() that make user wait ,like get data from network or database.
You can not load whole Layout in background thread(pls note AsyncTask.postExecute() is executed on main thread). Because all the UI components should be modified from only Main Thread(also called UI thread). You can use the background thread just to gather the information that is needed for displaying UI.
I need to make a transition screen, ou just put a dialog, because the app give a black screen when is creating the database.
I have google, and find some solutions for this. One of then, is just put a progress dialog when the database is been created.
My problem, and newbie question is, where do i put the progress dialog.
A -> BlackScreen -> B where A is the inicial menu, and B the other screen. I have tried to put the dialog on A and/or in B and dont work. So where can i put the code of the progress dialog, so it shows in the BlackScreen ?
Make use of Asyntask . put your database operation of creating database in asyntask in pre execute start dialog post execute cancel dialog in background perform database operation
http://developer.android.com/reference/android/os/AsyncTask.html
For that You have to use Async task :
class DownloadAsyncTask extends AsyncTask<String, String, Void>
{
ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(Login.this, "", "Please Wait ...");
}
#Override
protected Void doInBackground(String... arg0) {
//Do your Task
}
#Override
protected void onProgressUpdate(String...values){
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Void result){
super.onPostExecute(result);
progressDialog.dismiss();
}
}
//Create the Object
DownloadAsyncTask downloadAsyncTask = new DownloadAsyncTask();
downloadAsyncTask.execute();
now till your work get's completed it shows progress dialog inside the doInbackground write your logic and onPostExecute dismiss the dialog and call Intent of other Activity.