Android Progress Dialog не отображается

1

Это обработчик в основном потоке, который показывает и отклоняет диалог прогресса.

public static final int SHOW = 0;
public static final int DISMISS = 1;
public Handler pdHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        Log.i(TAG, "+ handleMessage(msg:" + msg + ")");
        switch(msg.what) {
        case SHOW:
            pd = ProgressDialog.show(LogViewer.this, "", getText(R.string.loading_msg), true);
            break;
        case DISMISS:
            if(pd != null) {
                pd.dismiss();
                pd = null;
            }
            break;
        }
    }
};

Сообщение о прогрессе:

        pdHandler.sendMessage(pdHandler.obtainMessage(SHOW));

Сообщение об увольнении:

        pdHandler.sendMessage(pdHandler.obtainMessage(DISMISS));

Это хорошо работает, когда я вызываю его, прежде чем запускать AsyncTask, AsyncTask onPostExecute() отклоняет его.

Но когда он запускается в runnable (runOnUiThread), диалог не отображается. Изучение pd в отладчике, он показывает, что он создан, он запущен и он виден, но на практике он не отображается.

Любое предложение?

UPDATE:
Я сделал очевидный тест, который я должен был сделать в первую очередь. Я прокомментировал сообщение DISMISS. И диалог прогресса появился. Оказалось, что слишком поздно, после того, как закончилась побежка.
Теперь я понял, что сообщение DISMISS отклонило еще не видимый ProgressDialog, поэтому я его не видел.
Теперь вопрос становится следующим: мне нужно, чтобы ProgressDialog отображался до запуска исполняемого кода. И это не так прямо. Моя иерархия вызовов такова:

onScrollEventChanged
    --> runOnUiThread ( 
        --> checkScrollLimits
            --> if need to scroll
                 show ProgressDialog "Loading"
                 get new data into table
                 dismiss ProgressDIalog
    )

Я пробовал что-то вроде этого:

onScrollEventChanged
    --> checkScrollLimits
        --> if need to scroll
             show ProgressDialog "Loading"
             --> runOnUiThread ( 
                 get new data into table
                 dismiss ProgressDIalog
             )

Но все же сообщение об увольнении попало туда до того, как может показать ProgressDialog.

В соответствии с Logcat существует пятисекундный интервал между приходом сообщения SHOW и приходом сообщения DISMISS.

ОБНОВЛЕНИЕ II:
Хотя я буду использовать метод isShowing() для ProgressDIalog

pd = ProgressDialog.show(...)
while(!pd.isShowing());

Но это совсем не помогает, оно возвращает true, даже если диалог пока не отображается.

Теги:
runnable
progressdialog
visibility

3 ответа

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

Я сделал это, превратив код в AsyncTask и используя блоки try/catch.

См. мой ответ в этом сообщении

Я не уверен, нужна ли AsyncTask, но после того, как я это сделал, блок try/catch сделал разницу.

2

Возможно, вы НЕ должны использовать runOnUiThread() и лучше справитесь с этим с помощью функции Looper.prepare():

Какова цель Looper и как его использовать?

Кроме того, ваш AsyncTask завершен и запущен в onPostExecute(), тогда вы находитесь в пользовательском интерфейсе, поэтому необязательный runOnUiThread().

  • 0
    Спасибо, я посмотрю на использование петлителя. :::: AsyncTask был примером, где обработчик работает как положено. Я не запускаю runOnUiThread на AsyncTask. Runnable связан с другим кодом в приложении, где мне нужно представить тот же ProgressDialog, там я использую runOnUiThread.
0

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

pdHandler.sendMessage(pdHandler.obtainMessage(DISMISS));

вам нужно поместить все эти тяжелые заявления или работать в другой поток, отличный от ui. Обработчик используется, чтобы поместить сообщение в очередь сообщений Thread, если ваш поток будет занят, тогда он выполнит это сообщение после предыдущего messsage. Поэтому из-за вашей тяжелой работы в этом диалоговом окне не обновляется. Всегда пользуйтесь услугами для работы в фоновом режиме. Никогда не пытайтесь помещать все в свой поток пользовательского интерфейса.

Надеюсь, что это поможет вам в противном случае использовать AsyncTask, это лучший способ делать такие вещи. Если все же вы столкнулись с одной и той же проблемой, отправьте этот код с того места, куда вы отправляете сообщение обработчику.

Ещё вопросы

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