2012-08-16 37 views
0

我有一個帶有類的Android應用程序,WifiAudioActivity擴展了Activity類。Android應用進度條在使用線程和AsyncTask時不會更新

簡而言之,當按下應用程序上的按鈕時,將運行一個方法,該方法使用進度條顯示方法的進度。

我顯示進度條並使用AsyncTasks進行更新。

問題是,爲了獲得方法的進度,我讓它在另一個線程上運行,因此線程可以不斷更新進度值,並將其顯示在進度中酒吧。但是,當我調用progessUpdate(),其中更新進度條,我設置該方法在線程運行,它不更新進度欄,它甚至不跳轉到onProgressUpdate()方法代碼。

有趣的是,我可以使用虛擬值更新進度,然後使用該方法運行線程。

我認爲這是我的線程有問題 - 任何人都可以幫忙嗎?

private ProgressDialog downloadAllDialog; 
private ProgressDialog usingDialog; 

private int totalDownloadSize; 

private Download downloadAll; 

private int totalBlocksLeft; 

private boolean downloadComplete; 
private boolean downloadFailed; 

public void downloadAllClick(View view)  //When the download all button is clicked 
{ 
    new PerformTask().execute(); 
} 

private class PerformTask extends AsyncTask<Void, Integer, Integer> 
{ 
    protected void onPreExecute() 
    { 
     showDialog(); 
    } 

    protected Integer doInBackground(Void... voi) 
    { 
     int retryCount = 0; 

     downloadComplete = false; //Assume the download is not complete 
     downloadFailed = false; 

     totalBlocksLeft = 0; 

     progressUpdater.run();  //Running method thread 

     publishProgress(20);  //THIS DOES NOT WORK 

     while ((retryCount < Consts.RETRY_TOTAL) && (!(downloadComplete))) 
     { 
      int blocksDownloaded = 0; 

      while ((downloadComplete == false) && (downloadFailed == false)) 
      { 
       blocksDownloaded = totalDownloadSize - downloadAll.getTotalBlocksLeft(); //GOT FROM THE RUNNING THREAD METHOD 

       publishProgress(blocksDownloaded); //DOES NOT WORK 
      } 

      ... 
     } 

     return totalBlocksLeft ; 
    } 

    Thread progressUpdater = new Thread() 
    { 
     @Override 
     public void run() 
     { 
      downloadComplete = downloadAll.downloadAudio(totalBlocksLeft); //Download the audio 

      if (!(downloadComplete)) 
      { 
       downloadFailed = true; 
      } 
     } 
    }; 

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

    protected void onPostExecute(Integer result) 
    { 
     removeDialog(); 
    } 
} 

protected Dialog onCreateDialog() 
{ 
    downloadAllDialog = new ProgressDialog(this); 

    downloadAllDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 

    downloadAllDialog.setMax(totalDownloadSize); 

    downloadAllDialog.setProgress(0); 

    downloadAllDialog.setMessage("Download All"); 

    usingDialog = downloadAllDialog; 

return downloadAllDialog; 
} 

}

因爲它的立場,在代碼的鍵位:

blocksDownloaded = totalDownloadSize - downloadAll.getTotalBlocksLeft(); //GOT FROM THE RUNNING THREAD METHOD 

publishProgress(blocksDownloaded); //DOES NOT WORK 

blocksDownloaded,從線程中運行的方法獲取其更新後的值,與最新進展情況。我確定這在技術上並不正確,但是讓AsyncTask中的線程真正運行該方法,同時在主方法中獲取進度更新。因此,只有進度條的更新不起作用。

+0

你並不需要一個線程所有,你的做法是錯誤的,首先你在的AsyncTask的doInBackground做runOnUIThread的這是錯誤的,你應該只做runOnUIThread中的UI相關的東西。那麼你不需要progressUpdater線程,因爲AsyncTask本身是一個最優線程。嘗試重構並使代碼可讀,以便有人可以幫助您。 – 2012-08-16 13:13:50

+0

正如你會注意到的,你告訴我要修復的,正是我的問題 - 我不知道該怎麼做。如果方法不在單獨的線程上運行,getTotalBlocks()方法將不會獲取新值。 – 2012-08-16 13:17:57

回答

1

看來你沒有正確使用AsyncTask。您似乎在UI線程上調用了下載代碼,可能會阻止progressBar更新。

我可以提出以下建議。這將確保您正確使用AsyncTask。當你正確使用AsyncTask時,代碼也應該得到很多簡化。

  1. 請勿創建任何線程並且不要使用runOnUIThread方法。 AsyncTask爲您提供了在適當的線程上運行的回調方法。
  2. 主要的下載代碼應該在doInBackground方法中。
  3. 您應該在下載代碼中的某處調用publishProgress。
+0

感謝您的建議,但將下載代碼放在doInBackground方法中並不是真的可行,因爲它分佈在4個類中,是一個絕對巨大的方法。 我已經刪除了runOnUIThread,但我仍然無法解決如何同時下載和更新進度欄。 – 2012-08-16 14:32:32

+1

如果您正在單獨的線程上運行下載,則應該調用progressUpdater.start()而不是progressUpdater.run() – Sameer 2012-08-16 14:44:35

+0

非常感謝!不完全確定爲什麼,但這是固定的! – 2012-08-16 14:53:08

0

你需要調用

progressUpdater.start(); 

,而不是

progressUpdater.run(); 
+0

謝謝,這就是Sameer告訴我的。不過謝謝! – 2012-08-17 10:08:07