ProgressDialog не появляется, пока не стало слишком поздно

1

Я пишу операцию, которая извлекает XML из Интернета через HTTP, а затем анализирует его в DOM. Затем он извлекает некоторые требуемые данные из DOM.

Как вы можете себе представить, это занимает несколько секунд, поэтому я поместил этот код в свой собственный поток, а затем попытался настроить отображение ProgressDialog, пока пользователь этого ждет.

Проблема заключается в том, что ProgressDialog вообще не отображается. Если я удалю вызов увольнять(), то он отображается после завершения работы и, очевидно, просто сидит там...

Вот мой код:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    progressDialog = ProgressDialog.show(this, "", "Loading...", true);
    Thread downloadThread = new Thread(new DownloadVerseThread());
    downloadThread.start();
    setContentView(R.layout.main);
    TextView verseView = (TextView) findViewById(R.id.displayFighterVerse);
    TextView dateView = (TextView) findViewById(R.id.displayDateRange);
    TextView referenceView = (TextView) findViewById(R.id.displayReference);
    try {
        downloadThread.join();
    } catch (InterruptedException e) {
        Log.e(TAG, "Attempted to set the UI values before we were ready.");
        return;
    }
    Log.d(TAG, "Date: " + date);
    Log.d(TAG, "Reference: " + reference);
    Log.d(TAG, "Scripture: " + scripture);
    progressDialog.dismiss();
    dateView.setText(date);
    referenceView.setText(reference);
    verseView.setText(scripture);
}



private class DownloadVerseThread implements Runnable {


    @Override
    public void run() {

        try {
            FighterVerseDownloader downloader = new FighterVerseDownloader();
            date = downloader.getDateRange();
            reference = downloader.getReference();
            scripture = downloader.getScripture();
        } catch (FighterVersesException e) {
            Log.e("FighterVerses", "Failed to get the Fighter Verse", e);
        }           
    }

}

Конструктор FighterVersesDownloader - это то, где выполняется вся работа с точки зрения HTTP и DOM.

Любые идеи о том, что мне не хватает? Я видел несколько подобных потоков при использовании AsyncTask, но я хотел использовать хорошие старомодные потоки напрямую, и предлагаемые решения не применяются.

Теги:

2 ответа

3
Лучший ответ

Я думаю, проблема может быть связана с тем, как вы выполняете потоковую обработку. Когда вы вызываете downloadThread.join(), вы в основном принимаете этот дорогой код и шлепаете его прямо в середине метода, блокируя поток пользовательского интерфейса в процессе.

Вам нужно использовать метод обратного вызова для обработки изменений пользовательского интерфейса при завершении потока. Ваш код должен выглядеть примерно так:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    progressDialog = ProgressDialog.show(this, "", "Loading...", true);
    Thread downloadThread = new Thread(new DownloadVerseThread());
    Handler downloadHandler = new Handler();
    Runnable downloadCallback = new Runnable (){
        public void run(){
                setContentView(R.layout.main);
            TextView verseView = (TextView) findViewById(R.id.displayFighterVerse);
            TextView dateView = (TextView) findViewById(R.id.displayDateRange);
            TextView referenceView = (TextView) findViewById(R.id.displayReference);
            Log.d(TAG, "Date: " + date);
            Log.d(TAG, "Reference: " + reference);
            Log.d(TAG, "Scripture: " + scripture);
            progressDialog.dismiss();
            dateView.setText(date);
            referenceView.setText(reference);
            verseView.setText(scripture);
        }
    };
    downloadThread.start();
}

private class DownloadVerseThread implements Runnable {
    @Override
    public void run() {

        try {
            FighterVerseDownloader downloader = new FighterVerseDownloader();
            date = downloader.getDateRange();
            reference = downloader.getReference();
            scripture = downloader.getScripture();
            downloadHandler.post(downloadCallback);
        } catch (FighterVersesException e) {
            Log.e("FighterVerses", "Failed to get the Fighter Verse", e);
        }           
    }
}

Это будет поддерживать загрузку в фоновом потоке до тех пор, пока она не будет закончена, а не почти сразу же отменит ее обратно в поток пользовательского интерфейса, как это было ранее.

EDIT: Здесь, где я узнал об этом.

  • 0
    Идеально - это сработало! Спасибо
3

Я бы рекомендовал использовать AsyncTask для таких вещей.

  • 0
    Мне было бы интересно узнать, что сообщество думает о преимуществах AsyncTask по сравнению с потоками "старой школы" ...
  • 0
    Есть много вопросов по этому поводу. Просто для ссылки: stackoverflow.com/questions/2523459/handler-vs-asynctask
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню