0

當我在backgroud後臺線程AsyncTask中創建AlertDialog時,出現錯誤。如果我在AsyncTask之外創建AlertDialog,它的工作很好。我如何解決這個問題?AsyncTask中的Android java AlertDialog錯誤

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(); 


      } 
     }); 

錯誤:

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() 
+0

什麼樣的錯誤?你可以添加完整的堆棧跟蹤嗎? – mrek

+1

通過在'execute'方法中傳遞'new Runnable()'你試圖做什麼?並且'execute'不是'static'方法如何使用類名來訪問它? –

+2

由於AsynTask的'doInBackground()'在工作線程上運行,因此您不需要'AsyncTask'內的'Runnable()'。你可以通過asynctask的其他方法訪問應用程序ui。所以在排序AsyncTask是用更有效的方式替代你的'Runnable'和'Message Handler'。 – user370305

回答

0

你應該尋找更成什麼AsyncTask做和爲什麼。

這是一個便利的類,允許在後臺完成工作。 doInBackground方法允許長時間運行的工作不阻止UI線程。

但是,如果要在UI線程上顯示或執行任務,則需要確保在UI線程上發生了。例如,您的線路:

onPreExecute執行,因爲它影響了UI。同樣地:

alertDialog2.show() 

正在嘗試更改UI。這應該在onPostExecute中運行。

雖然從根本上說,構建一個AlertDialog並不是一個長期運行的任務。除非您有意展開在顯示下一個對話框之前發生的事情,否則這些都不在AsyncTask之內。

看到這個帖子在這裏:http://blog.nikitaog.me/2014/10/11/android-looper-handler-handlerthread-i/

+0

我不明白我需要做什麼。 – Ron

0

不能與主UI線程交互非。 這裏的短期解決方案是:

Handler handler = new Handler(Looper.getMainLooper()); 
    handler.post(new Runnable() { 
     @Override 
     public void run() { 
      // Call UI related methods. 
     } 
    }); 
+0

它的工作,但現在我沒有看到ProgressDialog。所有這些代碼都在onActivityResult中。 – Ron

0

我猜的AsyncTask實現你的代碼是這樣的:

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();