0

As all we know android dialogs can be only created and show under main UI thread.

The problem is that i have a progress bar and a lot of work being done in a thread and in some part of the progress i must display a dialog and the user must select an option to get the work continuing.

So.. i need to display a dialog in a thread (blocking the thread until the user has selected an option).

I tryed it with this code

public void showDialog(Activity activity) {
    Looper.prepare();
    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);

    // set title
    alertDialogBuilder.setTitle("");

    // set dialog message
    alertDialogBuilder
        .setMessage(R.string.STREAM_NOT_WIFI)
        .setCancelable(false)
        .setPositiveButton(R.string.STREAM_NOT_WIFI_YES, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                preload=true;
            }
        })
        .setNegativeButton(R.string.CANCEL, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();
                preload=false;
            }
        });

    // create alert dialog
    AlertDialog alertDialog = alertDialogBuilder.create();

    // show it
    alertDialog.show();
}

but i got this message and the dialog is not being showed:

"attempting to initialize hardware acceleration outside of the main thread, aborting"
NullPointerException
  • 36,107
  • 79
  • 222
  • 382

2 Answers2

1

There're built in methods in Activity and in View which you can use to post task into UI-thread from non UI-thread. One of them is runOnUiThread of Activity.

Sample:

public class MainActivity extends Activity {

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        Thread thread = new Thread(new Runnable() {

            private final Object lock = new Object();
            private volatile boolean isEnabled = true;

            @Override public void run() {

                while (isEnabled) {
                    try {
                        Log.e("sample", "working...");
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        //
                    }


                    runOnUiThread(new Runnable() {
                        @Override public void run() {
                            AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                            builder.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
                                @Override public void onClick(DialogInterface dialog, int which) {
                                    synchronized (lock) {
                                        lock.notify();
                                    }
                                }
                            });
                            builder.show();
                        }
                    });

                    synchronized (lock) {
                        try {
                            Log.e("sample", "work stopped. Waiting for dialog click.");
                            lock.wait();
                        } catch (InterruptedException e) {
                            //
                        }
                    }

                }

            }
        });
        thread.start();
    }
}

Sample looks messy nevertheless it shows basics of running tasks from non UI-thread. Activity starts Thread which "works" for 5 seconds and then asks user to continue. When user tap on dialog's button then thread continues to execute work.

eleven
  • 6,779
  • 2
  • 32
  • 52
  • if i run the dialog on ui thread with runonuithread, then, the dialog it is not blocking my thread process until the user press the button. the thread is continuing – NullPointerException Feb 27 '15 at 12:46
  • @AndroidUser99 you have to block your thread "manually". A `Dialog` can't and shouldn't block you thread. Please read carefully my sample. – eleven Feb 27 '15 at 12:49
  • i will try to understand your lock and to add blocking logic to my code, but i will need time, the code is huge – NullPointerException Feb 27 '15 at 12:49
  • @AndroidUser99 if my answer helped you somehow consider voting up or marking it as answer. – eleven Feb 27 '15 at 15:57
0

You cannot simple call Looper.prepare() and have any thread display on the UI thread. You need the background thread to interact with the UI thread, which has restrictions.

Here is a good SO question related to this, but be sure to read 3 or 4 answers (not just the first one) and the question itself is in regards to a Toast - ignore that. The problem you have is similar...

Can't create handler inside thread that has not called Looper.prepare()

Also, you can see a tutorial about this type of problem here:

http://codetheory.in/android-handlers-runnables-loopers-messagequeue-handlerthread/

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