Это обработчик в основном потоке, который показывает и отклоняет диалог прогресса.
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, даже если диалог пока не отображается.
Я сделал это, превратив код в AsyncTask и используя блоки try/catch.
См. мой ответ в этом сообщении
Я не уверен, нужна ли AsyncTask, но после того, как я это сделал, блок try/catch сделал разницу.
Возможно, вы НЕ должны использовать runOnUiThread()
и лучше справитесь с этим с помощью функции Looper.prepare()
:
Какова цель Looper и как его использовать?
Кроме того, ваш AsyncTask
завершен и запущен в onPostExecute()
, тогда вы находитесь в пользовательском интерфейсе, поэтому необязательный runOnUiThread()
.
Я думаю, что это не сработает. Место, откуда вы отправляете сообщение
pdHandler.sendMessage(pdHandler.obtainMessage(DISMISS));
вам нужно поместить все эти тяжелые заявления или работать в другой поток, отличный от ui. Обработчик используется, чтобы поместить сообщение в очередь сообщений Thread, если ваш поток будет занят, тогда он выполнит это сообщение после предыдущего messsage. Поэтому из-за вашей тяжелой работы в этом диалоговом окне не обновляется. Всегда пользуйтесь услугами для работы в фоновом режиме. Никогда не пытайтесь помещать все в свой поток пользовательского интерфейса.
Надеюсь, что это поможет вам в противном случае использовать AsyncTask, это лучший способ делать такие вещи. Если все же вы столкнулись с одной и той же проблемой, отправьте этот код с того места, куда вы отправляете сообщение обработчику.