2016-07-06 4 views
0

Во время приложения android onCreate У меня есть куча кода, который может замедляться на некоторых старых устройствах. Я хочу, чтобы во время выполнения кода инициализации отображался индикатор прогресса. Диалог не будет отображаться, если вызван из onCreate, потому что дополнительный код блокирует пользовательский интерфейс. Поэтому он должен войти в AsyncTask.show progressdialog не отображается в asyctask

Это моя задача.

class startupTask extends AsyncTask<Void, Void, Void> { 

    @Override 
    protected void onPreExecute() { 
     pd = new ProgressDialog(mainContext); 
     pd.setMessage("Starting up. Please wait..."); 
     pd.setIndeterminate(true); 
     pd.setCancelable(false); 
     pd.show(); 

     super.onPreExecute(); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     MainActivity.this.runOnUiThread(new Runnable() { 
      public void run() { 
       pd.show(); 
       runInit(); 
      } 
     }); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     if (pd != null) { 
      pd.dismiss(); 
     } 
     super.onPostExecute(result); 
    } 
} 

Но диалог все еще не отображается? runInit - обычный медленный код запуска. Он должен работать в пользовательском интерфейсе.

Если я удалю вызов pd.dismiss, диалог выполнения появится после завершения кода инициализации, поэтому он создается ОК, просто не отображается.

Согласно другим сообщениям, приведенный выше код является правильным способом его выполнения, но когда вызывается из onCreate, он не работает?

Любые способы принудительного отображения диалогового окна после вызова? В любом случае я могу показать диалог и дождаться, пока он не станет видимым, прежде чем продолжить?

Спасибо за любую помощь.

EDIT: В конце концов мне просто пришлось укусить пулю и реорганизовать код, чтобы внутри AsyncTask был только медленный код не интерфейса. Это заставило его работать.

+0

Почему вы называете 'pd.show()' в 'doInBackground'? – Sharj

+0

Просто попытка получить диалог. Это не помогло. – Some1Else

+1

Ваша проблема заключается в утверждении: «runInit - это обычный медленный код запуска, который должен запускаться в пользовательском интерфейсе». Это нарушает цель асинктасы, которая заключается в перемещении этого материала из потока пользовательского интерфейса. Опишите, что делает runInit(), и кто-то может помочь вам найти способ сделать это вне потока пользовательского интерфейса. – alzee

ответ

0

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

+0

Да, runInit работает (и должен быть) в потоке пользовательского интерфейса. Есть ли другой способ, с помощью которого я могу показать прогресс в диалоговом окне перед запуском кода триада пользовательского интерфейса? – Some1Else

+0

Прогресс показывается, но заблокирован сразу после этого, я не должен запускать это в пользовательском интерфейсе или вы не следуете лучшим практикам. Чтобы помочь нам получить информацию о том, что делает runInit. –

0

onPreExecute(), onPostExecute() и onProgressUpdate() имеют доступ к потоку пользовательского интерфейса, но doInBackground() этого не делает.

Если runInit() что-то делает в пользовательском интерфейсе, он блокируется и может генерировать исключение, которое вы игнорируете.

Вы должны выполнить операции над doInBackground и использовать publishProgress() для отправки в onProgressUpdate() данных, которые вы хотите обновить до своего пользовательского интерфейса/состояния ProgressBar.

вот пример:

new AsyncTask<Void,Object,Void>() 
{ 
    @Override 
    protected Void doInBackground(Void... params) 
    { 
     Object[] _progress = new Object[]{"Decompressing", 1}; 
     publishProgress(_progress);    
    } 

    @Override 
    protected void onPostExecute(Void params) 
    { 

    } 
    @Override 
    protected void onPreExecute() 
    { 

    } 
    @Override 
    protected void onProgressUpdate(Object... values) 
    { 
     txtProgress.setText(values[0].toString()); 
     progressBar.setProgress(Integer.parseInt(values[1].toString())); 
    } 
}.execute();