Android java AlertDialog error in AsyncTask - java

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();

Related

AlertDialog not displaying from Inner Class

I've got a class inside my MainActivity class from which I'm trying to display an AlertDialog. The Dialog isn't showing and there are no errors. The code for the dialog is:
AlertDialog.builder builder = new AlertDialog.builder(MainActivity.this);
builder.setMessage("Unkown Game Code. please try again.").setTitle("Game Code Error").setNeutralButton("Okay", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
}
builder.create().show();
As the code is triggered when you receive a message via WebSocket, it might probably be async.
Try and run your code in your Activitys main Thread:
YourActivity.this.runOnUiThread(new Runnable() {
public void run() {
//Your Code
}
});

AlertDialog return boolean value

I am trying to include an AlertDialog builder within a method that prompts for a pin code and when the positive button is pressed, checks it against a database value and returns a true or false value to the method caller.
For example: Adding/editing/deleting a user task requires a pin code. I don't want to generate a different AlertDialog for all three (and more) of these actions. I want to wrap the following code within a TaskService class that I can call from any activity, and react based on the result from within that activity.
So TaskService.java would have:
public boolean isCorrectPin(View v){
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
final EditText editText = new EditText(context);
builder.setView(editText);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (editText.getText().toString()) == getPinCode(){
//return true
}
}
});
builder.show();
}
and OpenTaskAdapter.java would have:
public void onBindViewHolder(ViewHolder holder, int position){
holder.btnMarkAsComplete.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (service.isCorrectPin(v) {
//complete task
}
}
});
holder.btnDelete.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (service.isCorrectPin(v) {
//delete task
}
}
});
It's important to note that these two button listeners could be in totally different activities.
You can create your own method to generate dialog with listener:
public void isCorrectPin(Context context, String title, String message, String btnPositive, final DialogSingleButtonListener dialogSingleButtonListener) {
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle(title);
dialogBuilder.setMessage(message);
dialogBuilder.setPositiveButton(btnPositive, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (editText.getText().toString() == getPinCode()){
dialogSingleButtonListener.onButtonClicked(dialog);
}
}
});
AlertDialog dialog = dialogBuilder.create();
dialog.show();
}
And the listener class:
public interface DialogSingleButtonListener {
public abstract void onButtonClicked(DialogInterface dialog);
}
And use it like:
service.isCorrectPin(context, title, message, btnPositive
new DialogSingleButtonListener() {
#Override
public void onButtonClicked(DialogInterface dialog) {
//code here is only called if they entered a correct pin.
}
}
);
A dialog can't "return" a value in the way that it looks like you're expecting. A dialog can make changes to some other object, but you can't have a bit of code block on it and wait for the user to finish interacting with it.
Instead, you'll need to set up listeners for when the prompt dialog is dismissed or buttons or clicked, or whatever other event signals that you have what you need from it. Those listeners can then read the data gathered and set by the dialog.
this is how i'm doing :
public Boolean showAlert(String message)
{
action = false;
AlertDialog.Builder alertDialog = new AlertDialog.Builder(HAActivity.this);
// Setting Dialog Title
alertDialog.setTitle(getString(R.string.app_name));
// Setting Dialog Message
alertDialog.setMessage(message);
// Setting Icon to Dialog
// Setting Positive "Yes" Button
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
// Write your code here to invoke YES event
action = true;
}
});
// Setting Negative "NO" Button
alertDialog.setNegativeButton("Cancle", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to invoke NO event
action = false;
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
return action;
}
and calling function like this :
//activity in which you create function
if (Activity.showAlert("Do you really want to delete ??"))
{
//delete it anyway.
}

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

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);
}

How do I wait for user input when opening a alert dialog in android

Okay, so I wrote this code, where I use a thread to open some alert dialogs. The problem is that the thread doesn't wait for the first dialog to close before opening the second dialog. As you can see in the code I used wait() between opening the two dialogs and usenotify() in the onClick events of the buttons in the dialogs. I use the runOnUidThread() function to show the created dialogs. For some reason, when I open the activity the dialogs won't open and the app will have a black screen and the app will eventualy stop working. When I comment out the wait() statements (including the try and catch statements), the activity shows both the alert dialogs after each other. So is it even possible to wait for user input like this? Or am I doing something completly wrong. Thank you. HEre is my code :
public class EditTagActivity extends Activity
{
AlertDialog alertDialog1, alertDialog2;
Thread dialogManager = new Thread()
{
#Override
public void run()
{
runOnUiThread(showDialog1);
try
{
synchronized(dialogManager)
{
Log.d("Threads", "wait()");
dialogManager.wait();
}
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread(showDialog2);
try
{
synchronized(dialogManager)
{
Log.d("Threads", "wait()");
dialogManager.wait();
}
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread showDialog1 = new Thread()
{
#Override
public void run()
{
Log.d("Threads", "alertDialog1.show();");
alertDialog1.show();
}
};
Thread showDialog2 = new Thread()
{
#Override
public void run()
{
Log.d("Threads", "alertDialog2.show();");
alertDialog2.show();
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_tag);
Log.d("Threads", "setup()");
setup();
}
void setup()
{
Log.d("Threads", "g.run()");
createAlertDialog();
dialogManager.run();
}
void createAlertDialog()
{
Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Alert");
alert.setMessage("Flaq");
alert.setPositiveButton("OK", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
synchronized(dialogManager)
{
dialogManager.notifyAll();
}
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
synchronized(dialogManager)
{
dialogManager.notifyAll();
}
}
});
alertDialog1 = alert.create();
alertDialog2 = alert.create();
}
}
Yes, just call the dialog.show() of the second dialog in the onClick of the first dialog's setPositiveButton. This way the second dialog will be forced to wait until the first one is dismissed.
Why are you using threads to wait for user input? A dialog has to be run on the UI-thread as stated in the android training guide: "Every app has its own special thread that runs UI objects such as View objects; this thread is called the UI thread."
A dialog will occupy the UI-thread until it is dismissed. On close you can process the user input on a background thread.
Here are some good references:
https://developer.android.com/training/multiple-threads/communicate-ui.html
http://developer.android.com/guide/topics/ui/dialogs.html
void createAlertDialog()
{
Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Alert");
alert.setMessage("Flaq");
alert.setPositiveButton("OK", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
/*
Handle user input on other thread. With for example AsyncTask
*/
alertDialog2 = alert.create();
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
/*
Handle user input on other thread. With for example AsyncTask
*/
}
});
alertDialog1 = alert.create();
}

android display dialogbox during progressbar

I have this problem: during a long operation, I display a ProgressBar. Sometimes, during this operation, the programm has to ask the user for somewhat.
Then, I'd like to display a DialogBox, but if I do that, I get an error, since a DialogBox cannot be displayed during a Thread.
How can I solve my problem?
Please use AsyncTask Instead of thread then it will work you cannot perform UI related work in thread.
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
Read about AsyncTask
http://developer.android.com/reference/android/os/AsyncTask.html
Android supports the usage of the standard Java Thread class to perform asynchronous processing.
Android also supplies the java.util.concurrent package to perform something in the background, e.g. using the ThreadPools and Executor classes.
If you need to update the user interface from a new Thread, you need to synchronize with the user interface thread.
http://www.vogella.com/articles/AndroidBackgroundProcessing/article.html
i think this is what u want.
To start the operation:-
new StartTask().execute("");
StartTask Class:-
public class StartTask extends AsyncTask<String, Integer, String> {
private ProgressDialog pdialog;
#Override
protected void onPreExecute() {
// UI work allowed here
pdialog = new ProgressDialog(syncContext);
// setup dialog here
pdialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pdialog.setMessage("Updating...");
pdialog.setCancelable(false);
pdialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
if(pdialog != null) {
pdialog.dismiss();
}
if(progress[0] == 0) {
AlertDialog.Builder alertbox = new AlertDialog.Builder(context);
alertbox.setCancelable(false);
alertbox.setMessage("This is first Alert").setPositiveButton("OK",
new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
pdialog.show();
}
});
alertbox.create();
alertbox.show();
} else if(progress[0] == 1) {
AlertDialog.Builder alertbox = new AlertDialog.Builder(context);
alertbox.setCancelable(false);
alertbox.setMessage("This is second Alert").setPositiveButton("OK",
new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
pdialog.show();
}
});
alertbox.create();
alertbox.show();
}
}
#Override
protected void onPostExecute(String returnVal) {
// UI work allowed here
if(pdialog != null) {
pdialog.dismiss();
}
}
#Override
protected String doInBackground(String... params) {
for(int i = 0; i < 3; i++) {
//do some work here
publishProgress(i);
}
}
}

Categories

Resources