2012-03-09 68 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