2011-10-10 42 views
6

Ứng dụng của tôi tìm nạp một số mã html từ internet và khi hoàn tất, hiển thị nó trên màn hình thiết bị. Vì phải mất khoảng 3-4 giây để làm điều đó, trong thời gian này màn hình vẫn đen, tôi muốn sử dụng hộp thoại tiến trình. Đây là mã của tôi:Hộp thoại tiến trình Android

package com.nextlogic.golfnews; 



// ALL THE IMPORTS .... 

public class Activity1 extends Activity { 

    private ProgressDialog progressDialog; 
@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main2); 

     progressDialog = ProgressDialog.show(Activity1.this, "", "Loading..."); 
     new Thread() 
     { 
      public void run() 
      { 

      try 
       { 
       sleep(2000); 

      // HERE I'VE PUT ALL THE FUNCTIONS THAT WORK FOR ME 
} 
    catch (Exception e) 
    { 
     Log.e("tag",e.getMessage()); 
    } 
// dismiss the progressdialog 
    progressDialog.dismiss(); 
} 
}.start(); 

Chương trình hoạt động nhưng không hiển thị gì nữa. Tôi có một lỗi trong logcat:

Only the original thread that created a view hierarchy can touch its views. 

Bạn có thể giúp tôi được không? Cảm ơn trước.

+0

Những câu trả lời đưa ra là đúng, nhưng tôi muốn thêm một cái gì đó. ProgressDialogs có 2 kiểu: STYLE_SPINNER (mặc định) và STYLE_HORIZONTAL. Theo [hộp thoại ui] (http://developer.android.com/guide/topics/ui/dialogs.html), chúng ta nên làm theo [hướng dẫn thiết kế cho Tiến trình & Hoạt động] (http://developer.android.com /design/building-blocks/progress.html) và sử dụng STYLE_HORIZONTAL (nếu có liên quan và có thể). Về vấn đề này tôi thấy [hướng dẫn này] (http://www.pavanh.com/2013/04/android-progress-dialog-example.html) rất hữu ích. Bây giờ bạn có sự lựa chọn phong cách của ProgressDialog bạn muốn ... –

Trả lời

17

Lỗi này đủ rõ ràng. Để cập nhật một đối tượng trực quan, bạn phải chạy các thay đổi bên trong chuỗi chính. Một sửa chữa nhanh chóng và bẩn có thể được gọi mã cập nhật bên trong runOnUiThread().

Tuy nhiên, trong trường hợp của bạn, tôi sẽ sử dụng AsyncTask để tải xuống và cập nhật tiến độ của thanh tiến trình. Tác vụ có thuộc tính chạy trên chuỗi giao diện người dùng khi nó kết thúc (để bạn có thể cập nhật các chế độ xem ở đó, chẳng hạn như loại bỏ hộp thoại tiến trình)

Here là ví dụ về cách sử dụng AsyncTask để hiển thị hộp thoại tiến trình tải xuống.

Cập nhật

Stackoverflow đã có câu trả lời cho tất cả câu hỏi của bạn. Here là ví dụ về AsyncTask để tải xuống một số nội dung và hiển thị tiến trình tải xuống. Chỉ là những gì bạn muốn.

Cập nhật 2

Ok ở đây là mã của bạn sử dụng một AsyncTask:

public class Activity1 extends Activity 
{ 
    private ProgressDialog progressDialog; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     new AsyncTask<Integer, Integer, Boolean>() 
     { 
      ProgressDialog progressDialog; 

      @Override 
      protected void onPreExecute() 
      { 
       /* 
       * This is executed on UI thread before doInBackground(). It is 
       * the perfect place to show the progress dialog. 
       */ 
       progressDialog = ProgressDialog.show(Activity1.this, "", 
         "Loading..."); 
      } 

      @Override 
      protected Boolean doInBackground(Integer... params) 
      { 
       if (params == null) 
       { 
        return false; 
       } 
       try 
       { 
        /* 
        * This is run on a background thread, so we can sleep here 
        * or do whatever we want without blocking UI thread. A more 
        * advanced use would download chunks of fixed size and call 
        * publishProgress(); 
        */ 
        Thread.sleep(params[0]); 
        // HERE I'VE PUT ALL THE FUNCTIONS THAT WORK FOR ME 
       } 
       catch (Exception e) 
       { 
        Log.e("tag", e.getMessage()); 
        /* 
        * The task failed 
        */ 
        return false; 
       } 

       /* 
       * The task succeeded 
       */ 
       return true; 
      } 

      @Override 
      protected void onPostExecute(Boolean result) 
      { 
       progressDialog.dismiss(); 
       /* 
       * Update here your view objects with content from download. It 
       * is save to dismiss dialogs, update views, etc., since we are 
       * working on UI thread. 
       */ 
       AlertDialog.Builder b = new AlertDialog.Builder(Activity1.this); 
       b.setTitle(android.R.string.dialog_alert_title); 
       if (result) 
       { 
        b.setMessage("Download succeeded"); 
       } 
       else 
       { 
        b.setMessage("Download failed"); 
       } 
       b.setPositiveButton(getString(android.R.string.ok), 
         new DialogInterface.OnClickListener() 
         { 

          @Override 
          public void onClick(DialogInterface dlg, int arg1) 
          { 
           dlg.dismiss(); 
          } 
         }); 
       b.create().show(); 
      } 
     }.execute(2000); 

     new Thread() 
     { 
      @Override 
      public void run() 
      { 

       // dismiss the progressdialog 
       progressDialog.dismiss(); 
      } 
     }.start(); 
    } 
} 
+0

Bạn có thể vui lòng giúp tôi? Tôi mới vào android và tôi không hoàn toàn hiểu ví dụ đó. – Teo

+0

Hãy xem bản cập nhật –

+0

Vấn đề là .. Tôi không muốn thay đổi chức năng của mình vì chương trình hoạt động tốt, chậm một chút. Tôi muốn đặt các hàm đó trong một chuỗi nền và trong khi các hàm đó đang thực thi, tôi muốn hiển thị hộp thoại tiến trình. – Teo

1

Tạo một thread UI sau khi hoàn thành mạng lưới hoạt động

runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
      progressDialog.dismiss(); 

      } 
     }); 
4

Bạn cần phải làm theo cách này

runOnUiThread(new Runnable() { 
    public void run() { 
     // Do Your Stuff 
    }}); 
+0

và tôi bỏ qua tiến trìnhDialog ở đâu? – Teo

+0

tôi cho rằng bạn chỉ cần thực hiện một hàm trong đó viết mã trên và thay thế cho mã ghi chú để loại bỏ hộp thoại và gọi sự vui vẻ từ nhiệm vụ ur bất cứ khi nào bạn cần – MKJParekh

2

Bỏ thoại của bạn như thế này:

Handler handler = new Handler(); 
handler.post(new Runnable(){ 
    public void run(){ 
     progressDialog.dismiss(); 
    } 
}); 
+0

Tôi đã thay thế 'progressDialog.dismiss();' bằng mã của bạn. Bây giờ chương trình bị treo. – Teo

+0

đặt dòng này Handler handler = new Handler(); ra khỏi chủ đề .... –

+0

Tôi đã làm điều này, chương trình bị treo .. firs nó nói: 'Không thể tạo handler bên trong thread mà không được gọi là Looper.prepare()' và sau đó 'String ra khỏi giới hạn – Teo

Các vấn đề liên quan