gpt4 book ai didi

android - 为什么我会在这种状态下得到 NPE

转载 作者:太空宇宙 更新时间:2023-11-03 10:42:28 25 4
gpt4 key购买 nike

我正在尝试从设备录制音频。

我创建了一个 AudioRecord 对象并在 Activity 周期内对其进行管理。

当我的应用进入后台时它会停止,而当它进入前台时它会继续。

当录音运行时,我想从录音机中获取样本到一个字节数组

这是我用来执行此操作的代码:

private void startRecorder() {
Log.d(TAG, "before start recording");
myBuffer = new byte[2048];
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_DTMF, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
myRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 2048);

myThread = new Thread() {
public void run() {
while (true) {
if (myRecorder != null && myRecorder.getState() == AudioRecord.RECORDSTATE_RECORDING) {
myRecorder.read(myBuffer, 0, 2048);
recordingSampleNumber++;
if (recordingSampleNumber % 10 == 0) {
Log.d(TAG, "recording sample number:" + recordingSampleNumber);
}
}
}
}
};
myThread.setPriority(Thread.MAX_PRIORITY);

myRecorder.startRecording();
myThread.start();
Log.d(TAG, "after start recording");
}

我的问题是:每隔一段时间我就会收到以下错误:

06-22 11:44:21.057: E/AndroidRuntime(17776): Process: com.example.microphonetestproject2, PID: 17776
06-22 11:44:21.057: E/AndroidRuntime(17776): java.lang.NullPointerException: Attempt to invoke virtual method 'int android.media.AudioRecord.getState()' on a null object reference
06-22 11:44:21.057: E/AndroidRuntime(17776): at com.example.microphonetestproject2.MicrophoneTestApp$3.run(MicrophoneTestApp.java:108)

我的问题是:为什么我会在 myRecorder.getState() 前半行收到 NPE,而我写了 "if myRecorder!=null"

最佳答案

这看起来像是一个并发问题。

似乎在检查 myRecorder != null 之后,该变量实际上在另一个线程中设置为 null,这是可能的,因为您可能知道线程是并行运行的。

我建议您锁定对象并执行循环。然后,没有人会在不适当的地方访问它,即出乎意料。

while (true) {
synchronized (myRecorder) {
if (myRecorder != null && myRecorder.getState() == AudioRecord.RECORDSTATE_RECORDING) {
myRecorder.read(myBuffer, 0, 2048);
recordingSampleNumber++;
if (recordingSampleNumber % 10 == 0) {
Log.d(TAG, "recording sample number:" + recordingSampleNumber);
}
}
}
}

虽然这可能会解决您的问题,但您应该以其他方式处理它,例如不要将变量设置为 null 来取消线程,而是使用内置的 interruptjoin 方法:

private Thread mRecorderThread;

private void startRecorder() {
myRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 2048);

mRecorderThread = new Thread() {
public void run() {
while (true) {
if (!isInterrupted() && myRecorder.getState() == AudioRecord
.RECORDSTATE_RECORDING) {
myRecorder.read(myBuffer, 0, 2048);
recordingSampleNumber++;
if (recordingSampleNumber % 10 == 0) {
Log.d(TAG, "recording sample number:" + recordingSampleNumber);
}
}
}
}
};
mRecorderThread.setPriority(Thread.MAX_PRIORITY);
myRecorder.startRecording();
mRecorderThread.start();
Log.d(TAG, "after start recording");
}

private void stopRecorder() {
mRecorderThread.interrupt();
// Wait for the thread to finish (for the interruption to take effect)
try {
mRecorderThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
myRecorder.stop();
}

interrupt()正如您可能已经理解的那样,中断线程,但它不会立即终止它。在join()的帮助下您可以在中断后等待线程完成。

关于android - 为什么我会在这种状态下得到 NPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30975689/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com