因此,对于后台,我正在尝试创建一个通过麦克风连续记录并将数据存储在缓冲区中的应用程序。该程序的目标是对缓冲区中的数据执行某种类型的处理并对其进行操作。 目前,应用程序只是将数据读入缓冲区并尽快写入。在运行应用程序时,人们会对着麦克风说话,然后听到你刚刚说出来的声音从另一端传出来。
现在,我在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的一个单独的线程开始,以避免“应用程序没有响应...”问题,但这是另一个主题。我现在的主要目标是打破循环,我将不胜感激任何帮助或指导如何做到这一点。
答案 0 :(得分:4)
服务在
之下
问题#1:你无法摆脱循环。
问题#2:你的循环正在主应用程序线程上运行。
这很糟糕。
那么我的追索权是什么?
您将无限循环放在后台线程中,使用某些内容(例如,AtomicBoolean
)告诉该线程在需要时停止(例如onDestroy()
)。
我也意识到这个服务应该从UI的一个单独的线程开始,以避免“应用程序没有响应......”问题,但这是另一个主题。
不,这是同一个话题。
通过在循环中实例化一个新按钮来煽动某种方式突破
服务没有用户界面。
由于该活动中有一个“记录”按钮会触发对startService()
的调用,因此该活动可能会有一个“停止”按钮,触发对stopService()
的调用。
确定调用stopService()
的位置和方式后,您需要做的就是获取服务的onDestroy()
以使后台线程停止运行,因为onDestroy()
将是通过调用stopService()
触发。