Обозреватель 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
.