Android runOnUiThread 解释

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11254523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:32:15  来源:igfitidea点击:

Android runOnUiThread explanation

android

提问by user1154644

I am trying to display a progress dialog during the onCreate() method of one of my activities, have the work done to populate the screen done in a thread, and then dismiss the progress dialog.

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

Here is my onCreateMethod()

这是我的 onCreateMethod()

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

The populateTable method contains my thread and the code to dismiss the dialog, but for some reason. The activity comes up blank for about 10 secs(doing the populateTable() work), and then I see the screen. I never see the dialog displayed, any ideas?

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

Here is the populateTable() code:

这是 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();

}

回答by Cruceo

If you already have the data "for (Parcelable currentHeadline : allHeadlines)," then why are you doing that in a separate thread?

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

You should poll the data in a separate thread, and when it's finished gathering it, then call your populateTables method on the UI thread:

你应该在一个单独的线程中轮询数据,当它完成收集时,然后在 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");
            }
        }
    });
}

回答by K_Anas

This should work for you

这应该适合你

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

    }
}

回答by ToolmakerSteve

Instead of creating a thread, and using runOnUIThread, this is a perfect job for ASyncTask:

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

  • In onPreExecute, create & show the dialog.

  • in doInBackgroundpreparethe data, but don't touch the UI -- store each prepared datum in a field, then call publishProgress.

  • In onProgressUpdateread the datum field & make the appropriate change/addition to the UI.

  • In onPostExecutedismiss the dialog.

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

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

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

  • onPostExecute关闭对话框中。



If you have other reasons to want a thread, or are adding UI-touching logic to an existing thread, then do a similar technique to what I describe, to run on UI thread only for brief periods, using runOnUIThreadfor each UI step. In this case, you will store each datum in a local finalvariable (or in a field of your class), and then use it within a runOnUIThreadblock.

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