Caroline
Caroline

Reputation: 3913

Show an AlertDialog from a background Thread with the appcontext

Is possible to raise an AlertDialog from a background thread using a reference to getApplicationContext()?

I'm trying with that code but it doesn't work

    new Thread(){
        public void run(){
            new AlertDialog.Builder(appcontext)
            .setMessage("Test")
            .setPositiveButton("Ok", null)
            .show();
        }
    }.start();

Thanks in advance

Upvotes: 2

Views: 6967

Answers (5)

Tushar Mate
Tushar Mate

Reputation: 1

You cannot change UI in background thread. There is another thread to perform UI activities

runOnUiThread(new Runnable() {

                                        @Override
                                        public void run() {
                                            //perform UI operations
                                        }
                                    });

Upvotes: 0

Anuj Tenani
Anuj Tenani

Reputation: 2104

Simplest Solution is to use an AsyncTask.

try the following code

  private class LaunchDialog extends AsyncTask<Void,Void,Void>{
        Context context;
        public LaunchDialog(Context ctx){
           context =  ctx;
         }

    @Override
    protected  ArrayList<CategoryObj> doInBackground(Void... params) {
        //do the task to be done on NON-UI thread , or NON-Blocking thread
       // publishProgress(null);
    }

        @Override
        protected void onProgressUpdate(Void... v){
           //stuff done on UI thread , can be invoked from doInBackground

        }
    @Override
    protected void onPostExecute(Void x){
            //stuff to be done after task executes(done on UI thread)

         new AlertDialog.Builder(context)
            .setMessage("Test")
            .setPositiveButton("Ok", null)
            .show();

    }
    @Override
    protected void onPreExecute(){
             //stuff to be done before task executes (done on UI thread)
    }
}

to start the thread just do

new LaunchDialog(this).execute();

read article about painless threading here -- http://developer.android.com/resources/articles/painless-threading.html

Upvotes: 1

Alex
Alex

Reputation: 1056

you cannot access UI elements from a thread, you must create a handler and call it from your thread.

1- handler: to handle UI from other thread

 private Handler handler= new Handler() {
        public void handleMessage(Message msg){

            /*put your code here to update on UI*/

        } 
    }; 

2- in you thread call this:

  Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
          handler.sendEmptyMessage(0);
    } 
  }); //thread
t.start();

Upvotes: 1

Dan S
Dan S

Reputation: 9189

You'll have to get access to the UI thread, any of these: View.post(), Activity.runOnUiThread(), or obtaining and sending a Message.

Upvotes: 0

Rajiv Makhijani
Rajiv Makhijani

Reputation: 3651

No, you do not want to do this. Android does not permit UI work on any thread but the UI-thread because UI code is not thread safe. See "Painless Threading"1.

You can call Activity.runOnUiThread(Runnable) (on the specific activity) from another thread to force the code to run on the UI thread. You can also call View.post(Runnable) (on the specific view) to cause the action to be queued onto the UI thread. For more details on those options and others, see the above mentioned article.

However, Android also provides something called AsyncTask which is specifically designed for running some stuff on a separate thread, and some on the UI thread. This automatically uses Android's threadpool, and if you do not have any reason to use an explicit separate thread, is an easy, clean way to go:

From the Android docs:

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     // Runs on a ThreadPool thread
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             // Sends data to onProgressUpdate to run on the UI thread
             publishProgress((int) ((i / (float) count) * 100));
         }
         return totalSize;
     }

     // Runs on the UI thread!
     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     // Runs on the UI thread!
     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

Upvotes: 2

Related Questions