Search code examples
androidmultithreadingdialogandroid-dialoghardware-acceleration

It is possible to stop a thread until a dialog option has been chosed?


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"

Solution

  • 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.