Обозреватель Android runOnUiThread

Я пытаюсь отобразить диалог выполнения во время метода 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();

}

Ответ 1

Если у вас уже есть данные "для (Parcelable currentHeadline: allHeadlines)", то почему вы делаете это в отдельном потоке?

Вы должны опросить данные в отдельном потоке, и когда он завершит сбор, затем вызовите метод 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");
            }
        }
    });
}

Ответ 2

Это должно работать для вас

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

    }
}

Ответ 3

Вместо создания потока и использования runOnUIThread это идеальная работа для ASyncTask:

  • В onPreExecute создайте и покажите диалог.

  • в doInBackground подготовьте данные, но не прикасайтесь к пользовательскому интерфейсу - сохраняйте каждую подготовленную базу данных в поле, затем вызывайте publishProgress.

  • В onProgressUpdate прочитайте поле привязки и внесите соответствующие изменения/дополнения в пользовательский интерфейс.

  • В onPostExecute отпустите диалог.


Если у вас есть другие причины, по которым требуется поток, или добавление логики интерфейса UI к существующему потоку, выполните аналогичную технику, о которой я расскажу, для запуска в потоке пользовательского интерфейса только в течение коротких периодов, используя runOnUIThread для каждый шаг пользовательского интерфейса. В этом случае вы сохраните каждую базу данных в локальной переменной final (или в поле вашего класса), а затем используйте ее в блоке runOnUIThread.