2012-08-23 71 views
1

運行兩次我有一個Android應用程序,用Java編寫的,它使用的AsyncTask下載數據。該的AsyncTask需要處理其在整個下載顯示的進度對話框的AsyncTask和線程不會在Java/Android應用程序

實際下載是通過一個單獨的線程啓動的,downloadAllUpdater。雖然我知道這是不是慣例,因爲下載的過程中跨7類傳播,也沒有其他的方式來更新進度條而下載正在發生,因爲我無法運行publishProgress通話需要一個線程來自其他班級。

我的主要活動如下:

private Download downloadAll; 

private int totalBlocksLeft; 

private boolean downloadComplete; 
private boolean downloadFailed; 

private PerformTask currentPerformTask; 

public void downloadAllClick(View view) //When the download all button is clicked 
{ 
    currentPerformTask = new PerformTask(); 

    currentPerformTask.execute(); 
} 

private class PerformTask extends AsyncTask<Void, Integer, Integer> 
{ 
    protected void onPreExecute() 
    { 
     usingDialog = new ProgressDialog(WifiAudioActivity.this); 

     usingDialog.show(); 
    } 

    protected Integer doInBackground(Void... voi) 
    { 
     downloadAll = new Download(); 

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

     downloadAllUpdater.start(); 

     downloadFailed = false; 

     while ((downloadComplete == false) && (downloadFailed == false)) 
     { 
      blocksDownloaded = downloadAll.getTotalBlocksLeft(); 

      publishProgress(blocksDownloaded); 
     } 

     return 0; 
    } 

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

    protected void onPostExecute(Integer result) 
    { 
     usingDialog.dismiss(); 
    } 
} 

Thread downloadAllUpdater = new Thread() 
{ 
    public void run() 
    { 
     int runRetryCount = 0; 

     while ((!(downloadComplete)) && (!(downloadFailed))) 
     { 
      downloadComplete = download.downloadAudio(totalBlocksLeft); //Download the audio 

      if (!(downloadComplete)) 
      { 
       runRetryCount++; 
      } 

      if (runRetryCount > Consts.RETRY_TOTAL) 
      { 
       downloadFailed = true; 
      } 
     } 
    } 
}; 

下載與按鈕的點擊,從而開始downloadAllClick()方法開始。

這一切工作正常在第一時間按下按鈕。

然而,當按鈕被按下的第二時間(第一時間completition後),I接收錯誤,以及程序強制關閉。

我敢肯定錯誤是因爲我運行的線程,downloadAllUpdater第二次,因爲如果我那裏有downloadAllUpdater.start()一個單獨的方法,它也具有同樣的錯誤崩潰。

任何人都可以幫忙嗎?以下是錯誤日誌:

08-23 11:22:34.954: W/dalvikvm(1485): threadid=14: thread exiting with uncaught exception (group=0x400259f8) 

08-23 11:22:35.014: E/AndroidRuntime(1485): FATAL EXCEPTION: AsyncTask #5 

08-23 11:22:35.014: E/AndroidRuntime(1485): java.lang.RuntimeException: An error occured while executing doInBackground() 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at android.os.AsyncTask$3.done(AsyncTask.java:200) 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068) 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at java.lang.Thread.run(Thread.java:1102) 

08-23 11:22:35.014: E/AndroidRuntime(1485): Caused by: java.lang.IllegalThreadStateException: Thread already started. 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at java.lang.Thread.start(Thread.java:1331) 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at com.que.wifiaudio.WifiAudioActivity$PerformTask.doInBackground(WifiAudioActivity.java:518) 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at com.que.wifiaudio.WifiAudioActivity$PerformTask.doInBackground(WifiAudioActivity.java:1) 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at android.os.AsyncTask$2.call(AsyncTask.java:185) 

08-23 11:22:35.014: E/AndroidRuntime(1485):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 

08-23 11:22:35.014: E/AndroidRuntime(1485):  ... 4 more 

回答

2

您不能start a線程兩次。你可以做downloadAllUpdater一個Runnable來代替:

Runnable downloadAllUpdater = new Runnable() { //rest unchanged 

,取而代之的代碼doInBackground

new Thread(downloadAllUpdater).start(); 

這樣,一個新的線程創建的每個時間,運行相同的任務。

但是doInBackground已經在後臺線程上運行,你確定你需要創建一個新的線程?如果沒有,只需運行可運行程序:downloadAllUpdater.run();而不創建新線程。

+0

對不起,似乎沒有工作。如果我嘗試新的線程(downloadAllUpdater)。start();它給出了相同的錯誤,並且downloadAllUpdater.run()不更新進度條。 –

+0

如果您已將'downloadUpdater'設置爲Runnable並且每次啓動一個新線程(可能是不同的錯誤),您都不應該得到相同的錯誤?此外,您在線程('downloadComplete','totalBlocksLeft'和'downloadFailed')之間共享的所有變量都應該是不穩定的。 – assylias

+0

這絕對是一樣的錯誤,完全 - 顯然它不是線程?我會讓變量變得不穩定,只要有幫助。 –

0
runOnUiThread(new Runnable() { 

        @Override 
        public void run() { 
         // TODO Auto-generated method stub 

         //do you download here 

        } 
       }); 

內Asyctask如果這是有關您看到的錯誤,你不能訪問的事情發生在不同的theread

+0

但爲什麼它會第一次運行,而不是第二次 –

+0

理想情況下它第一次應該沒有。 –

1

不知道,但是你現有的代碼不是線程安全的。您當前正在分配來自兩個不同線程(PerformTaskdownloadAllUpdater)的成員變量downloadCompletedownloadFailed。這種用法會導致競賽條件和意想不到的結果。請閱讀concurrency in Java(即​​關鍵字),以同步您的線程。

+0

謝謝 - 我知道關於同步方法,不知道變量 –