2011-12-16 10 views
1

AsyncTaskでアクションを開始すると、ProgressDialog UIがフリーズする問題が発生しています。 私のバックグラウンドタスクは2つの部分で構成されているので、私の問題は他の同様の質問とは多少異なります。 - 最初の部分(loadDB())はデータベースアクセスに関連しています - 2番目の部分(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

+0

あなたの問題が解決したら、答えを受け入れることを忘れないでください! –

+0

ちょうどテストされ、美しく動作します。お二人のおかげです。 – user1099994

0

あなたがprogDialog AsyncTaskのpublishProgressメソッドを呼び出してはいけません。 setProgress(0);あなたが電話するときに。 また、ビルドツリーはブロックされるので、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 
    } 
} 
+0

上記のように、buildTree()は私が使用する外部コードなので、コードを書き直すのは簡単ではないかもしれません。しかし、ポインタをありがとう。 – user1099994