使用Android线程和AudioRecorder

时间:2012-03-06 18:05:16

标签: java android multithreading

我目前正在开发一个Android项目,其目标是录制音频并实时显示频谱图。我的设计包含三个主题:

  • UI-thread
  • 录音机主题
  • 多个分析线程

这个图表应该或多或少地显示它应该如何工作

      Start
UI  |-•-------------•----------•------•----------•------•----------•--
       \           / \        /      / \        /      / \        /
        \         /   \      /      /   \      /      /   \      /
Ana      \       /     |----|      /     |----|      /     |----|       ...
          \     /                 /                 /
           \   /                 /                 /
Rec     |---•-•-----------------•-----------------•--------------------
              Notify           Notify           Notify

为清楚起见,让我解释一下这是如何工作的。一开始,UI线程启动记录器线程。使用AudioRecord.setRecordPositionUpdateListener - 方法,定期通知主线程上的侦听器。该侦听器启动一个新线程进行分析。结果将返回到主线程,主线程使用AndroidPlot显示结果。

请注意,分析是低级写入的,因此分析帧所需的时间不会超过帧本身的长度。这意味着可以在必须分析新帧之前对帧进行分析。

更准确地说,我正在使用AsyncTask来解决所有这些问题。管理AudioRecord的类是AsyncTask,OnRecordPositionUpdateListener调用publishProgress返回主线程。在onProgressUpdate方法中,创建了一个扩展AsyncTask的AnalysisTask类的对象。分析结果使用get() - 方法收集并显示在UI线程中。

可悲的是,它并没有像预期的那样顺利。出现了许多问题:

1)GUI上有一个停止按钮。由于未阻止UI线程,因此用户应该能够使用它来停止该过程。但是当它被按下时,程序似乎冻结,并最终崩溃("application not responding")。

2)日志告诉我,在记录器线程上的通知和UI线程上的分析调用之间有很多时间。它甚至需要很长时间才会发生另一次通知。这会导致数据堆积,最终导致OutOfMemory错误。

3)当结果返回主线程时,redraw() - 调用与屏幕上图形的实际外观之间有很多时间。

鉴于处理器是单核的,大多数问题都可以通过线程的调度来解释,对吧?在这种情况下,它们是由于记录器线程非常繁忙导致UI线程调度得太晚,从而导致到达队列的任务与实际执行的任务之间出现延迟。

有没有办法解决这个问题?我可以阻止记录器线程占用所有CPU电源,而不会丢失帧或通知UI线程的规则性吗?我尝试了Thread.currentThread().setPriority(Thread.MIN_PRIORITY);但没有结果。

谢谢!

0 个答案:

没有答案