2012-03-09 65 views
5

我是新來的Android應用程序開發,並具有異步任務出現了問題。 所以我試圖創建一個ECG圖形應用程序,在圖形發生時進行一些後臺處理。的Android異步任務放慢我的UI線程

我已經定義了以下異步任務 -

private class Erosion extends AsyncTask <Void,Void,Void> { 


    @Override 
    protected Void doInBackground(Void...unused) { 

     int i,tempIndex; 
     double[] tempArray = new double[13]; 
     double min = ecgSamples[ecgSampleForErosionIndex] - gArray[0]; 
     while (ecgIncoming) 
     { 
      if (ecgSampleForErosionIndex > 179999) 
      { 
       ecgSampleForErosionIndex = 0; 
      } 

      for(i= 0;i<13;i++) 
      { 
       tempIndex = ecgSampleForErosionIndex + i; 
       if (tempIndex > 179999) 
       { 
        tempIndex = (ecgSampleForErosionIndex + i) - 180000; 
       } 
       tempArray[i] = ecgSamples[tempIndex] - gArray[i]; 
       if (tempArray[i] < min) 
       { 
        min = tempArray[i]; 
       } 

      } 

      //min needs to be stored in the erosionFirst Array 

      if (erosionFirstArrayIndex > 179999) 
      { 
       erosionFirstArrayIndex = 0; 
      } 


      ecgErosion[erosionFirstArrayIndex] = min; 
      erosionFirstArrayIndex++; 
      ecgSampleForErosionIndex++; 


     } 
     return null; 


    } 

    } //End of Async Task 

因此,所有我想要做的就是修改異步任務特定陣列的內容 - 我不需要更新UI(在至少不是現在)

然而,當我運行這個任務異步心電圖我圖形減慢,成爲幹。當我註釋掉「new Erosion()。execute();」在我開始異步任務的代碼中,圖形將再次變得正常。

是不是一個異步任務應該是在一個單獨的線程,因此不影響事情是如何在我的UI線程發生了什麼?我究竟做錯了什麼?

回答

8

即使您在後臺線程上運行一段繁重的代碼,它仍然會影響設備的CPU負載,因此也可能導致UI線程延遲,特別是如果設備具有單核CPU。

好像你在你doInBackground方法,它不斷地運行,並且只使用CPU不停,其中超載成爲一個非常沉重的循環。我不知道這是什麼環路是,但如果沒有不斷刷新你可能要考慮增加一個線程睡眠,從而允許其他線程獲得更多的CPU時間:

while (ecgIncoming) 
    { 
     ... do your thing ... 
     Thread.sleep(100); // wait for 100 milliseconds before running another loop 
    } 

顯然「 100" 只是一個數字,如果陣列可以更新一次,第二次,使之成爲1000,等...

+0

是的,我正在不斷運行異步任務,因爲我正在使用ECG數據來實時計算心率。這是相當繁重的工作 - 所以我想你的解釋是有道理的。除了Async任務外,還有別的東西可以用來執行常量後臺計算工作嗎? – stu90 2012-03-09 19:16:20

+3

@ stu90:「除了可用於執行常量後臺計算工作的異步任務外,還有別的東西嗎?」 - 沒有什麼會改變你的問題。該線程已被設置爲後臺優先級,但對於您所擁有的繁忙循環來說,這並沒有多大幫助。像這樣的忙碌循環在幾十年中被認爲是糟糕的形式。正如Talihawk所建議的那樣,您需要建立一個採樣率並允許其他線程有機會進入CPU。你也可以更好地服務你自己的線程,而不是無限期地從AsyncTask池中綁定一個線程。 – CommonsWare 2012-03-09 19:34:50

+0

@ stu90您可以使用服務而不是異步任務,但我懷疑這樣做會在性能上產生很大的差異。您可以將該服務授權在單獨的Linux進程上運行,但是我不能說這是否會或不重要。這應該可以幫助您開始:http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html – elevine 2012-03-09 19:35:13

0

以任何機會,你運行new Erosion().execute();多次?這可能會導致它,因爲您多次分配新的AsyncTask

+0

都能跟得上只有一次!但它在後臺運行了很長一段時間..所以我想這就是爲什麼它佔用了太多的CPU資源。 – stu90 2012-03-09 19:24:49