2012-06-29 43 views
23

Tôi đang cố gắng hiển thị hộp thoại tiến trình trong phương thức onCreate() của một trong các hoạt động của tôi, hoàn thành công việc để hoàn thành màn hình trong chuỗi và sau đó bỏ qua hộp thoại tiến trình.Android runOnUiThread Giải thích

Đây là onCreateMethod của tôi()

dialog = new ProgressDialog(HeadlineBoard.this); 
     dialog.setMessage("Populating Headlines....."); 
     dialog.show(); 
     populateTable(); 

Phương pháp populateTable chứa chủ đề của tôi và mã số để đóng hộp thoại, nhưng đối với một số lý do. Hoạt động này xuất hiện trống trong khoảng 10 giây (thực hiện công việc populateTable()), và sau đó tôi thấy màn hình. Tôi không bao giờ thấy hộp thoại được hiển thị, bất kỳ ý tưởng nào?

Đây là populateTable() code:

//Adds a row to the table for each headline passed in 
private void populateTable() { 
    new Thread() { 
     @Override 
     public void run() { 
      //If there are stories, add them to the table 
      for (Parcelable currentHeadline : allHeadlines) { 
       addHeadlineToTable(currentHeadline); 
      } 
       try { 
        // code runs in a thread 
        runOnUiThread(new Runnable() { 
          @Override 
          public void run() { 
           dialog.dismiss(); 
          } 
        }); 
       } catch (final Exception ex) { 
        Log.i("---","Exception in thread"); 
       } 
     } 
}.start(); 

} 
+1

'Nếu có câu chuyện, hãy thêm chúng vào bảng'. Bạn chạy mã này trên chuỗi giao diện người dùng chứ không phải trên chuỗi bạn đã tạo. –

+0

không chắc chắn những gì bạn đang đề xuất? – user1154644

+0

Di chuyển tất cả các mã trong runOnUiThread ra để void run(), chỉ để lại 'dialog.dismiss();' –

Trả lời

26

Nếu bạn đã có dữ liệu "cho (Parcelable currentHeadline: allHeadlines)," thì tại sao bạn làm điều đó trong một thread riêng biệt?

Bạn nên thăm dò ý kiến ​​các dữ liệu trong một thread riêng biệt, và khi nó được thu thập nó đã hoàn thành, sau đó gọi phương thức populateTables của bạn trên thread UI:

private void populateTable() { 
    runOnUiThread(new Runnable(){ 
     public void run() { 
      //If there are stories, add them to the table 
      for (Parcelable currentHeadline : allHeadlines) { 
       addHeadlineToTable(currentHeadline); 
      } 
      try { 
       dialog.dismiss(); 
      } catch (final Exception ex) { 
       Log.i("---","Exception in thread"); 
      } 
     } 
    }); 
} 
+0

Tôi đã thử điều này, nó chạy mà không cần ném ngoại lệ, nhưng tôi vẫn chưa bao giờ thấy hộp thoại, nó chỉ bị trống và sau đó hiển thị hoạt động khi màn hình đã được tạo. – user1154644

+0

Sau đó, bạn đang làm điều gì đó sai trái. Bạn đang tạo hộp thoại trong Chủ đề giao diện người dùng? Và tại sao bạn sử dụng HeadLineBoard.this? Tại sao không phải bối cảnh của bạn? – Guardanis

+0

không, hộp thoại được tạo trong onCreate() cho hoạt động. – user1154644

5

này nên làm việc cho bạn

public class MyActivity extends Activity { 

    protected ProgressDialog mProgressDialog; 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     populateTable(); 
    } 

    private void populateTable() { 
     mProgressDialog = ProgressDialog.show(this, "Please wait","Long operation starts...", true); 
     new Thread() { 
      @Override 
      public void run() { 

       doLongOperation(); 
       try { 

        // code runs in a thread 
        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          mProgressDialog.dismiss(); 
         } 
        }); 
       } catch (final Exception ex) { 
        Log.i("---","Exception in thread"); 
       } 
      } 
     }.start(); 

    } 

    /** fake operation for testing purpose */ 
    protected void doLongOperation() { 
     try { 
      Thread.sleep(10000); 
     } catch (InterruptedException e) { 
     } 

    } 
} 
+0

hmm..có vấn đề về cửa sổ bị rò rỉ. – user1154644

+0

trong giải pháp của bạn cố gắng thêm Thread.sleep (500) trước vòng lặp và xem những gì bạn nhận được !!, –

+0

cùng một hành vi. Tôi có khởi tạo ProgressDialog và show() trong phương thức onCreate() cho Activity, nếu nó quan trọng. – user1154644

2

Thay vì tạo chuỗi và sử dụng runOnUIThread, đây là công việc hoàn hảo cho ASyncTask:

  • Trong onPreExecute, hãy tạo & hiển thị hộp thoại.

  • trong doInBackgroundchuẩn bị dữ liệu, nhưng không chạm vào UI - lưu trữ mỗi dữ kiện chuẩn bị trong một lĩnh vực, sau đó gọi publishProgress.

  • Trong onProgressUpdate đọc trường dữ liệu & thực hiện thay đổi/bổ sung thích hợp cho giao diện người dùng.

  • Trong onPostExecute loại bỏ hộp thoại.


Nếu bạn có lý do khác để muốn có một chủ đề, hoặc đang thêm logic UI-chạm đến một chủ đề hiện có, sau đó làm một kỹ thuật tương tự với những gì tôi mô tả, để chạy trên thread UI chỉ cho ngắn gọn khoảng thời gian, sử dụng runOnUIThread cho mỗi bước giao diện người dùng. Trong trường hợp này, bạn sẽ lưu trữ từng mốc dữ liệu trong một biến địa phương final (hoặc trong một trường của lớp học của bạn), và sau đó sử dụng nó trong một khối runOnUIThread.

+0

Đã giúp rất nhiều !! Thêm tại http://developer.android.com/reference/android/os/AsyncTask.html – naren