Android 计时器似乎忽略了 .cancel
Android timer seems to ignore .cancel
我正在构建一个 Android 应用程序,它可以在打开某个 activity 时录制声音。我把录音功能分离在一个服务class中。我一直在使用 问题的答案并且有效。然而,我再次停止计时器时遇到了一些麻烦!
ArrayList<Double> decibelList = new ArrayList<>();
private MediaRecorder mRecorder = null;
Timer timer = new Timer();
RecorderTask recorderTask;
public void startRecorder() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
timer = new Timer();
recorderTask = new RecorderTask(mRecorder);
timer.scheduleAtFixedRate(recorderTask, 0, 400);
mRecorder.setOutputFile("/dev/null");
try {
System.out.println("--MediaRecorder started--");
mRecorder.prepare();
mRecorder.start();
} catch(IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private class RecorderTask extends TimerTask {
private MediaRecorder recorder;
public RecorderTask(MediaRecorder recorder) {
this.recorder = recorder;
}
public void run() {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
int amplitude = recorder.getMaxAmplitude();
double amplitudeDb = 20 * Math.log10((double) Math.abs(amplitude));
if (!String.valueOf(amplitudeDb).equals("-Infinity")) {
decibelList.add(amplitudeDb);
}
System.out.println("Current dB: " + amplitudeDb);
}
});
}
}
public void stopRecorder() {
if (mRecorder != null) {
if (timer != null) {
timer.cancel();
timer.purge();
timer = null;
}
try {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
} catch (RuntimeException stopException){}
}
}
然后在我的 activity.
中的 onBackPressed、onPause 和 onStop 中执行 stopRecorder 函数
如您所见,我已尝试通过 timer.cancel(); 停止它;但它继续 运行 尽管关闭 activity.
解决了我的问题。
原来我的取消确实有效,但我不小心启动了两个计时器!我通过添加检查我的计时器是否为空来解决了这个问题。
public void startRecorder() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setAudioEncodingBitRate(16);
mRecorder.setAudioSamplingRate(44100);
if (timer == null) {
timer = new Timer();
recorderTask = new RecorderTask(mRecorder);
timer.scheduleAtFixedRate(recorderTask, 0, 400);
}
mRecorder.setOutputFile("/dev/null");
try {
System.out.println("--MediaRecorder started--");
mRecorder.prepare();
mRecorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
以防万一有人想使用代码。
非常感谢您的评论!他们帮助我优化了我的代码。
我正在构建一个 Android 应用程序,它可以在打开某个 activity 时录制声音。我把录音功能分离在一个服务class中。我一直在使用
ArrayList<Double> decibelList = new ArrayList<>();
private MediaRecorder mRecorder = null;
Timer timer = new Timer();
RecorderTask recorderTask;
public void startRecorder() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
timer = new Timer();
recorderTask = new RecorderTask(mRecorder);
timer.scheduleAtFixedRate(recorderTask, 0, 400);
mRecorder.setOutputFile("/dev/null");
try {
System.out.println("--MediaRecorder started--");
mRecorder.prepare();
mRecorder.start();
} catch(IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private class RecorderTask extends TimerTask {
private MediaRecorder recorder;
public RecorderTask(MediaRecorder recorder) {
this.recorder = recorder;
}
public void run() {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
int amplitude = recorder.getMaxAmplitude();
double amplitudeDb = 20 * Math.log10((double) Math.abs(amplitude));
if (!String.valueOf(amplitudeDb).equals("-Infinity")) {
decibelList.add(amplitudeDb);
}
System.out.println("Current dB: " + amplitudeDb);
}
});
}
}
public void stopRecorder() {
if (mRecorder != null) {
if (timer != null) {
timer.cancel();
timer.purge();
timer = null;
}
try {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
} catch (RuntimeException stopException){}
}
}
然后在我的 activity.
中的 onBackPressed、onPause 和 onStop 中执行 stopRecorder 函数如您所见,我已尝试通过 timer.cancel(); 停止它;但它继续 运行 尽管关闭 activity.
解决了我的问题。
原来我的取消确实有效,但我不小心启动了两个计时器!我通过添加检查我的计时器是否为空来解决了这个问题。
public void startRecorder() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setAudioEncodingBitRate(16);
mRecorder.setAudioSamplingRate(44100);
if (timer == null) {
timer = new Timer();
recorderTask = new RecorderTask(mRecorder);
timer.scheduleAtFixedRate(recorderTask, 0, 400);
}
mRecorder.setOutputFile("/dev/null");
try {
System.out.println("--MediaRecorder started--");
mRecorder.prepare();
mRecorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
以防万一有人想使用代码。
非常感谢您的评论!他们帮助我优化了我的代码。