Android的runOnUiThread解释

我正在尝试在我的一个活动的onCreate()方法中显示进度对话框,完成工作来填充线程中完成的屏幕,然后closures进度对话框。

这是我的onCreateMethod()

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

populateTable方法包含我的线程和代码来closures对话框,但由于某种原因。 活动空白约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(); } 

如果你已经有数据“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"); } } }); } 

这应该适合你

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

而不是创build一个线程,并使用runOnUIThread ,这是一个ASyncTask完美的工作:

  • onPreExecute ,创build并显示对话框。

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

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

  • onPostExecuteclosures对话框。


如果您有其他理由需要一个线程,或者正在将UI触摸逻辑添加到现有的线程,那么请执行与我所描述的类似的技术,以在UI线程上仅在短时间内运行,为每个UI步骤使用runOnUIThread 。 在这种情况下,您将每个数据存储在本地finalvariables(或类中的一个字段)中,然后在runOnUIThread块中使用它。