【问题标题】:Android ProgressDialog with threading problem带有线程问题的Android ProgressDialog
【发布时间】:2011-02-25 21:13:07
【问题描述】:

我在进程运行时使用 ProgressDialog 时遇到问题。我已经尝试了所有可能的错误方法,并查看了许多网站,这些网站提供了我正在尝试做的示例,但是,我仍然遇到了在 ProgressDialog 出现之前线程正在运行的问题。这是我最近的尝试:

new Thread(new Runnable() {
     public void run() {
        dialog = new ProgressDialog(EPD.this);
        dialog.setMessage("Loading. Please Wait...");
        dialog.show();         
                    }
 }).run();
 getMostWanted();                       

除了尝试这种方式之外,我还尝试在 getMostWanted() 中创建一个新线程,但是我仍然得到相同的结果。当 getMostWanted() 没有对话框时,它会暂停约 4 或 5 秒。

提前感谢您的帮助。

【问题讨论】:

    标签: android multithreading progressdialog


    【解决方案1】:

    如果您在主线程上,您应该使用它来显示 ProgressDialog 并为getMostWanted() 分拆另一个线程。假设您希望getMostWanted() 的结尾关闭对话框,您应该查看AsyncTask

    private class GetMostWanted extends AsyncTask<Void, Void, Void> {
         private final ProgressDialog dialog;
    
         public GetMostWanted() {
              dialog = new ProgressDialog(EPD.this);
              dialog.setMessage("Loading. Please Wait...");
         }
    
         protected void onPreExecute() {
             dialog.show();
         }
    
         protected void doInBackground(Void... unused) {
             getMostWanted();
         }
    
         protected void onPostExecute(Void unused) {
             dialog.dismiss();
         }
     }

    这样您的处理将在doInBackground() 的后台线程上执行,然后在您完成后您可以在onPostExecute() 的主线程上关闭对话框。

    现在你可以使用了:

    new GetMostWanted(dialog).execute();

    【讨论】:

      【解决方案2】:

      @Amin 是正确的,解决问题的好方法是使用AsyncTask,尽管他的实现并不完全符合您的需求。您将在onPreExecute() 中创建您的对话框,并在onPostExecute() 中删除它。

      您遇到的问题是创建一个新的 Thread 然后调用 run 只会在 UI 线程上运行您的线程。您对 getMostWanted() 的调用也会在 UI 线程中执行,并阻止对话框的创建。

      因此,您的选择是按照其他人的建议使用AsyncTask,或者使用ThreadHandler,其中Handler 执行UI 更新。

      【讨论】:

        【解决方案3】:

        无法保证线程何时执行。我建议您改用 AsycTask 。这是一个例子。然后你可以执行它并更新你的进度条。

         private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
             protected Long doInBackground(URL... urls) {
                 int count = urls.length;
                 long totalSize = 0;
                 for (int i = 0; i < count; i++) {
                     totalSize += Downloader.downloadFile(urls[i]);
                     publishProgress((int) ((i / (float) count) * 100));
                 }
                 return totalSize;
             }
        
             protected void onProgressUpdate(Integer... progress) {
                 setProgressPercent(progress[0]);
             }
        
             protected void onPostExecute(Long result) {
                 showDialog("Downloaded " + result + " bytes");
             }
         }
        

        【讨论】:

          【解决方案4】:

          Jay...如果您想使用线程和处理程序。将时间密集型任务放入可运行的方法中。创建“包含”可运行对象的线程并调用线程启动,以便时间密集型任务在单独的线程上运行。您应该能够在 UI 线程中启动对话框。当后台线程完成并通知处理程序时,您应该能够关闭处理程序中绑定到 UI 线程的对话框。这是一些使用线程的代码。这个 sn-p 在一个新线程中启动一个耗时的进程。

          buttonConfuseText.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  final String inString= editTextPlainText.getText().toString();
                  Thread thread= new Thread( new Runnable() {
                      public void run() {
                          String outString= encrypt(password,inString); //<== time intensive task here
                          Message msg= Message.obtain();
                          Bundle b= new Bundle();
                          b.putString("encryptedText",outString);
                          msg.setData(b);
                          handler.sendMessage(msg);
                          Log.d(TAG,outString);
                      }
                  });
                  thread.setDaemon(true);
                  thread.start();
              }
          });
          

          你在这里等待线程完成:

          public class ConfuseText extends Activity {
              private Handler handler= new Handler(){
                  @Override
                  public void  handleMessage(Message msg){
                      super.handleMessage(msg);
                      ConfuseText.this.onThreadMessage(msg); //<== close dialog here if you wish
                  }
              };
          
          public void onThreadMessage(Message msg){
              Bundle b= msg.getData();
              String encryptedText="";
              if (b != null){
                  encryptedText= b.getString("encryptedText");
              }
              Log.d(TAG,encryptedText);
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多