Кажется, у меня постоянные проблемы с синхронизацией потоков и диалоговых окон. Я пытался использовать поток, или onCreate / onPrepare, или AsyncTask для некоторой загрузки / обработки в фоновом режиме. Чаще всего, когда фоновая обработка завершает и закрывает диалоговое окно, кажется, что элемент управления возвращается в корневой поток (поток Activity / UI?) до , когда диалог исчезает или выполняется процесс, подобный onPostExecute. , Это заставляет меня думать, что я делаю это неправильно. Вот типичная структура (псевдокод):
public class X {
protected String result = null;
protected ProgressDialog progressDialog;
public void onCreate() {
...
new XTask().execute();
progressDialog.show();
// result is null here, should be "hi"?
// do things with result, like barf on a NPE...sigh
}
private class XTask extends AsyncTask {
protected doInBackground() {
// Get URL.
// Look at contents, takes a few seconds.
// Return the result (should get sent to onPostExecute).
}
protected onPostExecute(r) {
result = r;
progressDialog.dismiss();
}
}
}
Я думаю, что после того, как doPostExecute устанавливает результат и закрывает диалоговое окно, обработка продолжается в методе onCreate. Однако результат часто (не всегда) равен нулю на этом этапе в onCreate. Есть лучший способ сделать это? Это только из-за общей хреновости эмулятора?
Спасибо.
Edit: чтобы быть более конкретным, моя задача (в doInBackground) выбирает URL и выполняет небольшую обработку ответа. Этот процесс занимает 1-3 секунды. Затем теоретически onPostExecute устанавливает X.result в то, что было извлечено. Я знаю, что содержание URL является действительным, и ответ хороший (не нулевой). Проблема в том, что в течение этих 1-3 секунд элемент управления возвращается в onCreate, как будто progressDialog вообще никогда не жил (он вообще не отображается в эмуляторе, но я думаю, это нормально).
Я думал, что вызов dialog.show () является методом блокировки, т. Е. Диалоговое окно появилось, и этот метод не продолжится, пока не исчезнет, но, похоже, это не так. Либо мой progressDialog.dismiss () вызывается до , следует, до установки X.result, либо вообще не вызывается, либо dismiss () происходит быстрее / до назначения, либо что-то еще полностью идет не так ...
Изменение порядка выполнения и progressDialog не помогает, равно как и перемещение его в onPreExecute (). Странно, onPostExecute не вызывается, пока я не вернусь в onCreate. Если у меня есть цикл Thread.sleep после выполнения (я думал, что это даст время), он никогда не завершит задачу, пока этот цикл не завершится, и я не вернусь. e.g.:
new XTask().execute();
int z=0;
while (response == null && z < 50) {
Thread.sleep(500);
z++;
}
if (response == null) return;
Метод задачи onPostExecute вызывается только после возврата. Хммм ... может быть, на onCreate это влияет.