0

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()
Ron
  • 399
  • 2
  • 6
  • 22
  • What kind of error? Can you add full stack trace please? – mrek Nov 20 '15 at 16:15
  • 1
    what you are trying to do by passing `new Runnable()` in `execute` method? and also `execute` is not `static` method how accessing it using class name ? – ρяσѕρєя K Nov 20 '15 at 16:15
  • 2
    You don't need `Runnable()` inside `AsyncTask` as AsynTask's `doInBackground()` runs on worker thread. and you can access application ui in other methods of asynctask. So in sort AsyncTask is substitute of your `Runnable` and `Message Handler` with more efficient way. – user370305 Nov 20 '15 at 16:17
  • I am also not sure I'd you are using asyncTask correctly, see [example](http://www.compiletimeerror.com/2013/01/why-and-how-to-use-asynctask.html?m=1) – mrek Nov 20 '15 at 16:18
  • @mrek I have a ProgressDialog before `new Runnable()`. I edited the code – Ron Nov 20 '15 at 16:18
  • @Ron: then `mDialog.dismiss();` line causing issue – ρяσѕρєя K Nov 20 '15 at 16:20
  • Not sure this is going to solve your problem but you could try adding: if (Looper.myLooper() == null) { Looper.prepare(); } in doInBackground() – mjp66 Nov 20 '15 at 16:21
  • @ρяσѕρєяK its not. without mDialog its not working too. @mjp66 its not working. The link of causing issue is `AlertDialog alertDialog = alertDialog2.create();` – Ron Nov 20 '15 at 16:25
  • By the way, it is better solution to use [anonymous class](http://stackoverflow.com/a/24827535/3894977) before Runnable - you have multiple methods there: onPreExecute, onPostExecute - where you can work with Views (show or hide something); then you have doInBackground(..) method, which is something like run in Runnable. I suggest you to read more in [official documentation](http://developer.android.com/reference/android/os/AsyncTask.html). In addition, I'd like to see **full** stack trace. – mrek Nov 20 '15 at 16:38

3 Answers3

0

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/

Jim
  • 10,172
  • 1
  • 27
  • 36
0

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.
        }
    });
kaspian
  • 93
  • 1
  • 1
  • 5
  • Its working but now I didnt see the ProgressDialog. all this code is in onActivityResult. – Ron Nov 20 '15 at 16:29
0

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();
Beeing Jk
  • 3,796
  • 1
  • 18
  • 29