2012-06-27 22 views
4

我有一個啓動長時間運行任務的按鈕的活動。我使用AsyncTask執行任務,並顯示隨任務進度更新的確定ProgressBar。在任務運行的第一次時,一切正常,但在隨後的運行中出現對話框,但已經達到100%和100/100。我在我的Activity中重寫onCreateDialog和onPrepareDialog。我推測使用setProgress(0)會重置對話框,但這不起作用。我在AsyncTask的onPrecute方法中使用showDialog,並在AsyncTask的onPostExecute中使用dismissDialog。唯一能夠讓對話框重置的方法是使用onPostExecute中的removeDialog,但我寧願不重新創建對話框,因爲我將重複使用多次。相關代碼如下。這是在API級別10如何清除重複使用的確定進度欄?

@Override 
protected Dialog onCreateDialog(int id) { 
    switch (id) { 
     case PROGRESS_DIALOG: 
      progressDialog = new ProgressDialog(ProtoBufSerializationTestActivity.this); 
      progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
      progressDialog.setCancelable(true); 
      progressDialog.setMax(100); 
      progressDialog.setMessage("Testing..."); 
      return progressDialog; 
     default: 
      return null; 
    } 
} 

@Override 
protected void onPrepareDialog(int id, Dialog dialog) { 
    super.onPrepareDialog(id, dialog); 
    switch (id) { 
     case PROGRESS_DIALOG: 
      ProgressDialog tmp = (ProgressDialog)dialog; 
      tmp.setProgress(0); 
      tmp.setSecondaryProgress(0); 
      return; 
     default: 
      Log.e("test", "Unknown dialog requested"); 
    } 
} 

private class SerializationTestTask extends AsyncTask<Void, Integer, Long> { 

    @Override 
    protected void onPreExecute() { 
     showDialog(PROGRESS_DIALOG); 
    } 

    @Override 
    protected Long doInBackground(Void... params) { 
     long accumulator = 0; 
     int totalSize = 0; 
     for (int i = 0; i < 10000; i++) { 
      final long start = System.nanoTime(); 
      //code to be timed 
      final long end = System.nanoTime(); 
      accumulator += end - start; 
      if (i % 100 == 0) { 
       publishProgress(i); 
      } 
     } 
     return accumulator; 
    } 

    @Override 
    protected void onPostExecute(Long aLong) { 
     dismissDialog(PROGRESS_DIALOG); 
     results.setText(String.format("Serialized Message 10000 times.\nAverage time to serialize %.3fms", (double) aLong/1e10)); 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
     progressDialog.incrementProgressBy(1); 
    } 

編輯採取@ Arhimed的建議,我結束了與下面的代碼之後。它更簡單。我本可以使用DialogFragment,但我不認爲這是必要的。

private class SerializationTestTask extends AsyncTask<Void, Integer, Long> { 
    private ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     dialog = ProgressDialog.show(ProtoBufSerializationTestActivity.this, "Serialization Test", "Testing...", false); 
    } 

    @Override 
    protected Long doInBackground(Void... params) { 
     long accumulator = 0; 
     int totalSize = 0; 
     for (int i = 0; i < 10000; i++) { 
      final long start = System.nanoTime(); 
      //code to be timed 
      final long end = System.nanoTime(); 
      accumulator += end - start; 
      if (i % 100 == 0) { 
       publishProgress(i); 
      } 
     } 
     return accumulator; 
    } 

    @Override 
    protected void onPostExecute(Long aLong) { 
     dialog.dismiss(); 
     results.setText(String.format("Serialized Message 10000 times.\nAverage time to serialize %.3fms", (double) aLong/1e10)); 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
     dialog.incrementProgressBy(1); 
    } 
} 

回答

1

以這種方式不可能使用ProgressDialog。您的AsyncTask應該每次創建一個新實例。

+0

爲什麼Android會對回調和緩存感到困擾呢?它僅用於不確定的ProgressDialogs嗎? Android開發指南的功能與我在做的幾乎相同http://developer.android.com/guide/topics/ui/dialogs.html#ProgressDialog。 – volker238

+0

@ volker238我不明白你的意見。回調是更新進度對話框,而不阻止UI線程。 – BDFun

+1

回調函數('onCreateDialog'和'onPrepareDialog')適用於'AlertDialogs'。然而,我遇到'ProgressDialog'不以這種方式工作 - 至少我無法重用'ProgressDialog'的一個實例,具體來說,不確定的進度微調不顯示動畫顯示同一個實例的秒數。所以我總是在'AsyncTask.onPreExecute()'中創建一個'ProgressDialog'的新實例,並在'AsyncTask.onPostExecute()'中將其關閉。這種方式很好。 –

0

實際上,setProgress(0)僅在進度開始時刷新顯示。 所以,你可以通過調用在onStart setProgress之前,像這樣的強制刷新:

@Override 
protected void onPrepareDialog(int id, Dialog dialog) { 
    super.onPrepareDialog(id, dialog); 
    ProgressDialog progress = (ProgressDialog)dialog; 
    progress.onStart(); 
    progress.setProgress(0); 
} 
2

其實Arhimed是正確的,你不能這樣做,但你可以強制進度條來其零狀態「髒'的方式。對我來說,客戶需要進度條以使其值無論如何,以防用戶離開該活動,但在我的情況下,進度仍然存在,並且只從開始重置。我已將自定義進度繪製爲可繪製並且setProgress根本沒有幫助我。所以我做的就是在實際設置REAL可繪製setProgressDrawable(null)之前調用這個方法,這是一種骯髒的方式清除,但它做你想做的事情,然後用你自己的progressdrawable調用相同的方法,所以它感覺像它已被刷新。這就是沒有其他的窪你不幸可以實現這一點。