2011-12-16 69 views
1

我在啓動AsyncTask中的操作時出現ProgressDialog UI凍結問題。我的後臺任務由兩部分組成: - 第一部分(loadDB())與數據庫訪問相關 - 第二部分(buildTree())與以下內容有關:構建ListView內容並使用runOnUiThread調用AsyncTask中的ProgressDialog未更新

進度對話框在任務的第一部分期間正確更新,但在2dn部分期間沒有正確更新。 我嘗試移動AsyncTask的onPostExecute中的buildTree部分,但它並沒有幫助,但是這部分代碼仍然會導致進度暫時凍結,直到完成該工作(有時很長時間)。我無法從頭開始重新編碼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

不要在UI線程內你的整個buildTree()方法。

而是希望只運行變化,使在UI線程的UI:

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

會嘗試這個,謝謝。 – user1099994 2011-12-16 11:45:16

+0

如果問題解決了,請不要忘記接受答案! – 2011-12-16 11:52:11

0

你應該叫的AsyncTask的publishProgress方法,而不是progDialog。 setProgress(0);當你打電話。 此外buildTree不會在UI線程上運行,因爲它會阻止它。 從doInBackground方法運行邏輯。

請注意,您實際上不會構建ListView,而應該構建它的數據模型。 look here

是這樣的:

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 
    } 
}