2012-06-29 5 views
23

Я пытаюсь отобразить диалог прогресса во время метода onCreate() одного из моих действий, выполнить работу, чтобы заполнить экран, сделанный в потоке, и затем отменить диалог прогресса.Android runOnUiThread объяснение

Вот мой 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

'Если есть истории, добавьте их в таблицу'. Вы запускаете этот код в потоке пользовательского интерфейса, а не в потоке, который вы создали. –

+0

не уверен, что вы предлагаете? – user1154644

+0

Переместить весь код в runOnUiThread из void run(), оставить только 'dialog.dismiss();' –

ответ

26

Если у вас уже есть данные "для (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"); 
      } 
     } 
    }); 
} 
+0

Я пробовал это, он работает без исключения исключения, но я все еще никогда не видят диалог, он просто пуст, а затем показывает активность после того, как экран был построен. – user1154644

+0

Тогда вы делаете что-то еще неправильно. Вы создаете диалог в потоке пользовательского интерфейса? И почему вы используете HeadLineBoard.this? Почему не ваш контекст? – Guardanis

+0

Нет, диалог создается в onCreate() для активности. – user1154644

5

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

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..получает проблему с утечкой окон. – user1154644

+0

в вашем решении попробуйте добавить Thread.sleep (500) перед циклом for и посмотреть, что вы получаете !!, –

+0

такое же поведение. У меня есть инициализация ProgressDialog и show() в методе onCreate() для Activity, если это имеет значение. – user1154644

2

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

  • В onPreExecute, создать & показать диалог.

  • в doInBackgroundподготовить данные, но не трогать UI - хранить каждую приготовленную опорную точку в поле, а затем вызвать publishProgress.

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

  • onPostExecute отклонить диалог.


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

+0

Помогли много! Подробнее на странице http://developer.android.com/reference/android/os/AsyncTask.html. – naren

Смежные вопросы