ProgressDialog в AsyncTask не обновляется - PullRequest
1 голос
/ 16 декабря 2011

У меня проблема с зависанием пользовательского интерфейса ProgressDialog, когда я запускаю действие в AsyncTask.Моя проблема несколько отличается от других подобных вопросов, потому что моя фоновая задача состоит из двух частей: - первая часть (loadDB ()) связана с доступом к базе данных - вторая часть (buildTree ()) связана с созданием ListView.содержимое и запускается с помощью вызова runOnUiThread

Диалог хода выполнения корректно обновляется во время 1-й части задачи, но не во время 2-й части.Я попытался переместить часть buildTree в OnPostExecute AsyncTask, но это не помогло, эта часть кода все еще заставляет прогресс временно зависать до тех пор, пока не будет выполнена эта (иногда довольно длительная) часть работы.Я не могу перекодировать часть buildTree с нуля, потому что она основана на внешнем коде, который я использую.

Любые советы, как решить эту проблему?Есть ли способ принудительно обновить какое-либо диалоговое окно на экране?

Код идет здесь:

public class TreePane extends Activity {

   private ProgressDialog progDialog = null;

   public void onCreate(Bundle savedInstanceState) {
       // first setup UI here
       ...

       //now do the lengthy operation
       new LoaderTask().execute();
   }

   protected class LoaderTask extends AsyncTask<Void, Integer, Void>
   {
        protected void onPreExecute() {
           progDialog = new ProgressDialog(TreePane.this);
           progDialog.setMessage("Loading data...");
           progDialog.show();
        }

        protected void onPostExecute(final Void unused) {
            if (progDialog.isShowing()) {
               progDialog.dismiss();
            }
        }

        protected void onProgressUpdate(Integer... progress) {
             //progDialog.setProgress(progress[0]);
        }

        protected Void doInBackground(final Void... unused) 
        {
            //this part does not block progress, that's OK
            loadDB();

            publishProgress(0);

            //long UI thread operation here, blocks progress!!!!
            runOnUiThread(new Runnable() {
                public void run() {
                   buildTree();
                }
            });

            return null;
        }
   }

   public void buildTree()
   {
      //build list view within for loop
      int nCnt = getCountHere();
      for(int =0; i<nCnt; i++)
      {
         progDialog.setProgress(0);
         //add tree item here
      }
   }
}

Ответы [ 2 ]

2 голосов
/ 16 декабря 2011

Не запускайте весь ваш метод buildTree() в потоке пользовательского интерфейса.

Вместо этого запустите только те изменения, которые вы хотите внести в пользовательский интерфейс в потоке пользовательского интерфейса:

protected Void doInBackground(final Void... unused) 
{
    //this part does not block progress, that's OK
    loadDB();
    publishProgress(0);
    buildTree();
    return null;
}

А потом:

public void buildTree()
{
    //build list view within for loop
    int nCnt = getCountHere();
    for(int =0; i<nCnt; i++)
    {
        progDialog.setProgress(0);
        runOnUiThread(new Runnable() {
            public void run() {
                // update your UI here and return
            }
        });
        // now you can update progress
        publishProgress(i);
    }
}
0 голосов
/ 16 декабря 2011

Вы должны вызывать метод publishProgress от AsyncTask, а не progDialog.setProgress (0);как ты называешь.Также buildTree не должен запускаться в потоке пользовательского интерфейса, так как он будет блокировать его.запустите логику из метода doInBackground.

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

как-то так:

protected Void doInBackground(final Void... unused) 
{
    //this part does not block progress, that's OK
    loadDB();
    publishProgress(0);
    buildTree();
}

public void buildTree()
{
    //build list view within for loop
    int nCnt = getCountHere();
    for(int =0; i<nCnt; i++)
    {
        publishProgress(i); //for exmple...
        //add tree item here
    }
}
...