27

我试图在我的一项活动的 onCreate() 方法期间显示进度对话框,完成在线程中填充屏幕的工作,然后关闭进度对话框。

这是我的 onCreateMethod()

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

populateTable 方法包含我的线程和关闭对话框的代码,但出于某种原因。活动出现空白大约 10 秒(执行 populateTable() 工作),然后我看到屏幕。我从来没有看到显示的对话框,有什么想法吗?

这是 populateTable() 代码:

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

}
4

3 回答 3

31

如果您已经拥有“for (Parcelable currentHeadline : allHeadlines)”的数据,那么为什么要在单独的线程中执行此操作?

您应该在一个单独的线程中轮询数据,并在完成收集数据后,然后在 UI 线程上调用您的 populateTables 方法:

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");
            }
        }
    });
}
于 2012-06-29T00:20:59.847 回答
12

这应该适合你

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

    }
}
于 2012-06-29T00:27:18.317 回答
5

这不是创建线程和使用,而是ASyncTaskrunOnUIThread的完美工作:

  • onPreExecute中,创建并显示对话框。

  • doInBackground 准备数据,但不要触摸 UI - 将每个准备好的数据存储在一个字段中,然后调用publishProgress.

  • onProgressUpdate读取数据字段并对 UI 进行适当的更改/添加。

  • onPostExecute关闭对话框中。


如果您有其他原因需要线程,或者正在向现有线程添加 UI 触摸逻辑,则执行与我描述的类似的技术,仅在 UI 线程上运行很短的时间,runOnUIThread用于每个 UI 步骤。在这种情况下,您会将每个数据存储在局部final变量(或类的字段)中,然后在runOnUIThread块中使用它。

于 2014-11-07T17:20:33.900 回答