Android ProgressDialog not showing (blocked by code in other Thread) - java

Looking to similar questions everybody solve the problem of not appearing their Progress Dialog putting the intermediate code in a separate Thread.
My problem is that the mentioned solution is not working for me.
In my activity:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.dialog_ddbb_download_text)
.setPositiveButton(R.string.Accept, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// In this method I show the progress dialog
showProgressAndDownloadDDBB();
}
})
.setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
// Create the AlertDialog object and return it
builder.create().show();
Method in the activity:
private void showProgressAndDownloadDDBB() {
progressDialog = new ProgressDialog(mContext);
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
progressDialog.show();
// Here I call the Runnable to execute the code in other Thread and let the UI draw the Progress Dialog. If it wasn't called, the progress dialog does appear.
DDBB_Download_Manager ddbb_download_manager = new DDBB_Download_Manager(mContext, progressDialog);
ddbb_download_manager.run();
}
My runnable class, expected to run the intermediate code in a separate Thread:
public class DDBB_Download_Manager implements Runnable {
public DDBB_Download_Manager(Context context, ProgressDialog progressDialog) {
this.mContext = context;
this.mProgresDialog = progressDialog;
}
#Override
public void run() {
someCode()
Thread.sleep(3000);
// The GUI shows the accept Button clicked for 3 seconds (like it was freezed)
// Here I try to hide the Progress dialog after finishing the job, but it doesn't matter becasuse the progress dialog didn't even show up.
View rootView = ((Activity)mContext).getWindow().getDecorView().findViewById(android.R.id.content);
rootView.post(new Runnable() {
#Override
public void run() {
mProgresDialog.dismiss();
}
});
}
So the question is:
if I am executing the code between the Show and Dismiss methods of the Progress Dialog in a different Thread than the UI Thread, why is not the dialog showing up?

In fact it appears If I don't call the Runnable.
That is because you are running directly the dismiss() method from the runnable when you call ddbb_download_manager.run() where the progress dialog is cleared/done and if you are not calling it then the progress dialog will show due to that dismiss is on yet been called.
Make sure that you call ddbb_download_manager.run() when you want your progress dialog to be dismissed. don't call it directly after you show your progress dialog.
private void showProgressAndDownloadDDBB() {
progressDialog = new ProgressDialog(mContext);
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
progressDialog.show();
// Here I call the Runnable to execute the code in other Thread and let the UI draw the Progress Dialog. If it wasn't called, the progress dialog does appear.
DDBB_Download_Manager ddbb_download_manager = new DDBB_Download_Manager(mContext, progressDialog);
Handler handler = new Handler();
handler.postDelayed(ddbb_download_manager ,3*1000);
}

Related

How to close a custom dialog automatically

I want to open a dialog. And dismiss automatically after a few seconds, the button in the dialog should also dismiss a dialog, whatever happens first. But I can't find the right way to close the dialog after time is up
I use the next custom dialog
private void okShowDialog(String title, String message){
vibrate();
final Dialog dialogo=new Dialog(Login.this);
dialogo.setContentView(R.layout.okdialog);
dialogo.setCancelable(false);
TextView errorTitle=dialogo.findViewById(R.id.lblTitleDialog);
errorTitle.setText(title);
TextView errorMessage=dialogo.findViewById(R.id.txtErrorDialog);
errorMessage.setText(message);
Button dialogButton = (Button) dialogo.findViewById(R.id.btnCont);
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
dialogo.show();
}
The dialog XML is very simple, it just shows a title, message, and button.
I've been through this for a couple of days and can't figure out how to solve it.
You can try to add Handler:
dialogo.show();
final Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
// Close dialog after 1000ms
dialogo.cancel();
}
}, 1000);
After 1000 ms (1 sec) Your dialog will be closed. I think that You don't have to check if a dialog was closed with a button and when You call again close on closed dialog You won't get any error but if I am not right just add a boolean variable to control if a dialog was closed by a button.
You could also use Kotlin Coroutine:
'build your dialog...'
dialog.setOnShowListener {
CoroutineScope(Dispatchers.Main).launch {
delay(length)
dialog.dismiss()
}
}
dialog.show()
Where 'length' is the time in milliseconds that you want the dialog to show for.

How to dismiss dialog box before further processing?

I have an alertDialog that takes input for further processing. Because the processing can take a while, I want to close the alertDialog and display an image during the time it is doing the process method. The problem is that process() is called before the dialog is actually dismissed. So during that loading time the program basically 'hangs', displaying the alert dialog until process() finishes, after which the image is shown for a split second, defeating its purpose.
I have tried showing the image in the process() method, and tried doing dialog.dismiss() in a synchronized method, but the result stays the same.
alertDialogBuilder.setCancelable(true).setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
final String input = et.getText().toString();
dialog.dismiss(); //finish this first
process(input); //then do this
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
You may use
alertDialogBuilder.setOnDismissListener(new
DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialogInterface) {
//do work on dismiss of dialog
}
});
So,you can show the image in this section and start your process as well. Add a callback listener to process end and use the callback to make the image invisible when the process ends.
It should be as simple as
final String input = et.getText().toString();
dialog.dismiss();
// run in background
AsyncTask.execute(new Runnable() {
#Override
public void run() {
process(input);
}
});

Android java AlertDialog error in AsyncTask

When I create AlertDialog in backgroud background thread AsyncTask, I get error. if I create AlertDialog outside of AsyncTask its working great. How I can fix that?
final ProgressDialog mDialog = new ProgressDialog(PageAndExercise.this);
mDialog.setMessage(getString(R.string.loading));
mDialog.setCancelable(false);
mDialog.show();
alertDialog2 = new AlertDialog.Builder(this);
AsyncTask.execute(new Runnable() {
#Override
public void run() {
mDialog.dismiss();
alertDialog2.setTitle(getString(R.string.tnxupload));
// Setting Dialog Message
alertDialog2.setMessage(getString(R.string.tnxupload2));
alertDialog2
.setCancelable(false)
.setPositiveButton("", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton(getString(R.string.tnxupload3), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
AlertDialog alertDialog = alertDialog2.create();
// show it
alertDialog2.show();
}
});
The error:
28928-31794/com.example.exampleE/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #5
Process: com.example.example, PID: 28928
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
You should look more into what AsyncTask does and why.
It is a convenience class to allow work to be done in the background. The doInBackground method allows long-running work to not block the UI thread.
However, if you want to display or perform tasks on the UI thread, you need to make sure those happen on the UI thread. For example, your line:
mDialog.dismiss();
should execute in onPreExecute because it impacts the UI. Likewise:
alertDialog2.show()
is trying to change the UI. This should be run in onPostExecute.
Fundamentally, though, building an AlertDialog is not a long running task at all. None of that needs to be in AsyncTask unless you have intentions to expand what happens prior to displaying the next dialog.
See this post here: http://blog.nikitaog.me/2014/10/11/android-looper-handler-handlerthread-i/
You can't interact with UI non from main-Thread.
The short solution here is:
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
// Call UI related methods.
}
});
I guess AsyncTask implement to your code is something like this:
final ProgressDialog mDialog = new ProgressDialog(this);
mDialog.setMessage("loading");
mDialog.setCancelable(false);
mDialog.show();
final AlertDialog.Builder alertDialog2 = new AlertDialog.Builder(this);
new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
super.onPreExecute();
mDialog.dismiss();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
AlertDialog alertDialog = alertDialog2.create();
alertDialog2.setTitle("tnxupload");
alertDialog2.setMessage("tnxupload");
alertDialog2.setCancelable(false).setPositiveButton("", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
}).setNegativeButton("tnxupload3", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
alertDialog2.show();
}
#Override
protected Void doInBackground(Void... params) {
return null;
}
}.execute();

Android: Progress Dialog shows a black screen

This is my code that am I using to implement a ProgressDialog when a camera fired and photo taken.
public void onPhotoTaken() {
_taken = true;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(_path, options);
try {
ProgressDialog dialog = ProgressDialog.show(this, "Loading", "Please wait...", true);
ExifInterface exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
On clicking on the save button of my android device, instead of displaying the Progress Dialog, it displays a black screen. Please what could be wrong.
You should remember when it comes to Progress dialog is that you should run it in a separate thread. If you run it in your UI thread you'll see no dialog.
If you are new to Android Threading then you should learn about AsyncTask. Which helps you to implement painless Threads.
Sample code:
private class CheckTypesTask extends AsyncTask<Void, Void, Void>{
ProgressDialog asyncDialog = new ProgressDialog(IncidentFormActivity.this);
String typeStatus;
#Override
protected void onPreExecute() {
//set message of the dialog
asyncDialog.setMessage(getString(R.string.loadingtype));
//show dialog
asyncDialog.show();
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
//don't touch dialog here it'll break the application
//do some lengthy stuff like calling login webservice
return null;
}
#Override
protected void onPostExecute(Void result) {
//hide the dialog
asyncDialog.dismiss();
super.onPostExecute(result);
}
}
Good luck.
EDIT
The method show() must be called from the User-Interface (UI) thread, while doInBackground() runs on different thread which is the main reason why AsyncTask was designed.
You have to call show() either in onProgressUpdate() or in onPostExecute
It is working for me just using your ProgressDialog line of code so the problem must be elsewhere but you can try:
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Please wait...");
dialog.setTitle("Loading");
dialog.show();

ProgressDialog not being displayed in Activity with custom View

I am developing an Android app which has 2 classes. Game, which extends Activity, and GameView, which extends View.
When the game is loaded, it sets the content view to GameView, which is just a drawing class that uses a canvas to display the game.
I am trying to create a ProgressDialog in the Game class which will show a spinner after a certain action has been done, as this takes a long time to complete. So far I have the following:
setContentView(R.layout.activity_game);
ProgressDialog pd = new ProgressDialog(this);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setMessage("Calculating hint");
pd.show();
AsyncTask<String[][], Void, SudokuSquare> nextSquareThread = new GetNextSquare().execute(puzzleNumbers);
next = nextSquareThread.get();
pd.dismiss();
setContentView(gameView);
And my AsyncTask class looks like this:
private class GetNextSquare extends AsyncTask<String[][], Void, SudokuSquare> {
private ProgressDialog dialog = new ProgressDialog(Game.this);
#Override
protected void onPreExecute() {
this.dialog.setMessage("Finding next number");
this.dialog.show();
}
#Override
protected SudokuSquare doInBackground(final String[][]... args) {
try {
SudokuAdvancedSolver solver = new SudokuSolver(args[0]);
return solver.getOneValue();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
#Override
protected void onPostExecute(final SudokuSquare result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
At the moment I have two ProgressDialogs, one inside the AsyncTask and one outside. Which one is correct? Also, the spinner is not being displayed at all. What am I overlooking which is causing this to be the case?
only the one outside is correct. because you are trying the main thread (the UI thread of your activity) by another thread (your asychronic task). you should use a handler in place of this :
1/ you show the progress bar
2/ you load the game in a thread
3/ when the game is loaded you send a message to the handler which will stop the progress bar.
See this exemple . you should dismiss your dialog in the handler (when the handler receives the message from the thread) .
If you don't implement a listener on Asynctask, i could suggest you to dismiss your progress dialog onPostExecute
private ProgressDialog dialog;
public void setProgressDialog(ProgressDialog dialog){
this.dialog = dialog;
}
#Override
protected void onPostExecute(final SudokuSquare result) {
dialog.dismiss();
}
and before you executing Asynctask add this code
nextSquareThread.setProgressDialog(pd);

Categories

Resources