使用appcontext从后台线程显示AlertDialog

时间:2011-08-26 01:06:24

标签: java android multithreading

是否可以使用对getApplicationContext()的引用从后台线程引发AlertDialog?

我正在尝试使用该代码,但它不起作用

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

提前致谢

5 个答案:

答案 0 :(得分:1)

不,你不想这样做。 Android不允许UI在任何线程上工作,但是UI线程,因为UI代码不是线程安全的。请参阅“无痛线程”1

您可以从另一个线程调用Activity.runOnUiThread(Runnable)(在特定活动上)以强制代码在UI线程上运行。您还可以调用View.post(Runnable)(在特定视图上)以使操作排队到UI线程上。有关这些选项和其他选项的更多详细信息,请参阅上述文章。

然而,Android还提供了一种名为AsyncTask的东西,它专门用于在一个单独的线程上运行一些东西,一些在UI线程上运行。这会自动使用Android的线程池,如果您没有任何理由使用显式的单独线程,那么这是一种简单,干净的方法:

来自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");
     }
 }

答案 1 :(得分:1)

您无法从线程访问UI元素,您必须创建一个处理程序并从您的线程中调用它。

1- handler:从其他线程处理UI

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

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

        } 
    }; 

2-你在线程中打电话给:

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

答案 2 :(得分:1)

最简单的解决方案是使用AsyncTask。

尝试以下代码

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

启动线程就行了

new LaunchDialog(this).execute();

在这里阅读有关无痛线程的文章 - http://developer.android.com/resources/articles/painless-threading.html

答案 3 :(得分:0)

您必须访问UI线程,其中任何一个:View.post()Activity.runOnUiThread()obtaining and sending a Message

答案 4 :(得分:0)

您无法在后台线程中更改UI。还有另一个线程可以执行UI活动

runOnUiThread(new Runnable() {

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