5

因此,对于背景,我正在尝试创建一个应用程序,该应用程序通过麦克风连续记录并将数据存储在缓冲区中。该程序的目标是对缓冲区中的数据执行某种类型的处理并对其采取行动。目前,应用程序只是将数据读入缓冲区并尽快写入。运行应用程序时,一个人会对着麦克风说话,然后听到你刚才说的话从另一端传出来。

现在,我对 Android 的缺乏经验开始浮出水面。我将读写操作作为无限循环进行。服务如下:

public class AudioService extends Service {

private final int MIC = AudioSource.MIC;
private final int SAMPLE = 44100;
private final int CHANNELI = AudioFormat.CHANNEL_IN_MONO;
private final int CHANNELO = AudioFormat.CHANNEL_OUT_MONO;
private final int FORMAT = AudioFormat.ENCODING_PCM_16BIT;
private final int BUFFERSIZE = AudioRecord.getMinBufferSize(SAMPLE,
        CHANNELI, FORMAT);
private final int STREAM = AudioManager.STREAM_MUSIC;
private final int MODE = AudioTrack.MODE_STREAM;
private boolean play = true;

AudioRecord recorder = null;
AudioTrack track = null;

short[] buffer = null;

public void OnCreate() {

}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    recorder = new AudioRecord(MIC, SAMPLE, CHANNELI, FORMAT, BUFFERSIZE);
    track = new AudioTrack(STREAM, SAMPLE, CHANNELO, FORMAT, BUFFERSIZE,
            MODE);
    buffer = new short[BUFFERSIZE];
    recorder.startRecording();
    track.play();

    while (play) {
        recorder.read(buffer, 0, buffer.length);
        track.write(buffer, 0, buffer.length);
    }
    return START_STICKY;
}

当在活动中单击“记录”按钮时,将调用此服务。我希望能够单击记录并可以选择单击取消以停止此循环。下面实现这个的监听器是:

private OnClickListener Recording = new OnClickListener() {
    public void onClick(View v) {

        serviceIntent = new Intent(getApplicationContext(),
                AudioService.class);
        serviceIntent.putExtra("extraData", "somedata");
        startService(serviceIntent);

        record.setEnabled(false);
        cancel.setEnabled(true);
        cancel.requestFocus();

};

现在问题变得很明显了。应用程序在到达 startService(serviceIntent) 时无法完成执行,只是在余额中徘徊。

那我有什么办法?我正在考虑某种方法来从无限循环内部控制服务,但我对 Android 的缺乏经验让我想知道如何做到这一点。通过在循环中实例化一个新按钮来激发某种中断;因此,在 startIntent 期间,我将能够跳出循环并“结束疯狂”。

任何帮助,将不胜感激。我也意识到这个服务应该在与 UI 不同的线程上启动,以避免“应用程序没有响应......”问题,但这是另一个话题。我现在的主要目标是打破循环,我将不胜感激有关如何做到这一点的任何帮助或指导。

4

1 回答 1

5

服务如下

问题#1:你没有办法跳出你的循环。

问题 #2:您的循环在主应用程序线程上运行。

这是不好的。

那我有什么办法?

您将无限循环放在后台线程中,使用某些东西(例如, an AtomicBoolean)告诉该线程在需要时停止(例如,onDestroy())。

我也意识到这个服务应该在与 UI 不同的线程上启动,以避免“应用程序没有响应......”问题,但这是另一个话题。

不,是同一个话题。

通过在循环内实例化一个新按钮来激发某种方式来打破

服务没有 UI。

由于您在该活动中有一个触发对 的调用的“记录”按钮startService(),那么也许该活动应该有一个触发对 的调用的“停止”按钮stopService()

一旦你确定了调用的位置和方式stopService(),那么你需要做的就是让onDestroy()你的服务让你的后台线程停止运行,这onDestroy()将由调用stopService().

于 2012-05-31T23:52:59.230 回答