(转)AudioRecord 释放资源错误(进程意外中断)
释放资源 即AudioRecord.release()方法,前两天自己随手想到的一个函数,写入还真有,而且正是想要的方法--释放当前占用的资源,但是在使用中可能遇到各种各样的问题,不适用它问题就更严重了。
目前很多网上关于AudioRecord的讲解都没有考虑release这个方法,或者google code上面一些方法不需要release资源。但是在用的时候,尤其来电时释放mic资源是一种必须的需求,所以还是要用到release方法释放mic资源。
个人感觉各式各样的网络流行版本中,http://blog.csdn.net/zhjp4295216/archive/2010/11/09 /5996735.aspx这个还是比较靠谱的一个,但是它说的释放mic资源根本无法完全释放,会在电话中出现断断续续的情况。但对于使用可以作为一个参照版本,还是不错。
先看看api上的介绍:
public void release ()
Since: API Level 3
Releases the native AudioRecord resources. The object can no longer be used and the reference should be set to null after a call to release()
你一定觉得这个解释非常恼火,起码我觉得是的。根据我使用的结果应该意思是:
释放之后这个对象不能再被使用,而且引用必须变null。像废话,就是翻译嘛,但是意思不仅仅是翻译。
两种最基本的错误方式:
1。在一个线程里面处理录音,然后继承Thread的类中提供方法release,然后电话来之前先stop,然后release。
2。像那个网址里面,但是在run最后加上release。电话来时、或者后台运行时先pause,然后start
据这两个例子,肯定都是错的。先说问题
1。先stop或suspend再release,本质上对于audiorecord的操作还没有结束,只是要求强制关闭(stop方法本身不安全)。还是会继续占用mic,所以释放就会造成线程意外结束,系统报出线程意外中断的错误。这就是the reference should be set to null。虽然来电的情况系统会自动为你再次开启,但是总不至于每次都让用户去看到程序中断吧。
2。先pause掉之后,程序正常隐蔽,但是由于程序还会在start再次调用record,虽然是重新生成一个新的。这就是object can no longer be used and the reference should be set to null。所以在重新回到程序时会抛出相同错误。
这里解决方案已经很明显了,就是在实例程序的run结尾加上ar.release();。 来电结束时重新生成一个新的线程,让原来的线程结束去吧!这样就可以再来电和后台时成功释放mic了,希望解释这两个错误能让你了解那句话和系统抛出的这个纠结的错误。
另外,那个实例有个错误,大家想必看到了吧,还是说一下,网上错误太多了:
public void start() {
// 在调用本线程的 Activity 的 onResume 里调用,以便 Activity 恢复后继续获取麦克风输入音量
if (!isRun) {
super.start();
isRun = true;
}
}
附:很多录音在模拟器是无法测试的,所以请在真机上测试,也所以才有这个纠结的不好找到源头的错误。
private final static int CHANNEL_MODE = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private final static int ENCODING = AudioFormat.ENCODING_PCM_8BIT;
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, RATE,
CHANNEL_MODE, ENCODING, CHUNK_SIZE_IN_SAMPLES * 2);
我记得貌似只支持这个,频率是最低的吧 起码44100不支持,你可以用AudioRecord.getMinBufferSize这个方法测试一下。有个外国的网站上有人统计过,但是找不到了,忘了保存起来了,只能分享这些了,呵呵。好了,就这些
目前很多网上关于AudioRecord的讲解都没有考虑release这个方法,或者google code上面一些方法不需要release资源。但是在用的时候,尤其来电时释放mic资源是一种必须的需求,所以还是要用到release方法释放mic资源。
个人感觉各式各样的网络流行版本中,http://blog.csdn.net/zhjp4295216/archive/2010/11/09 /5996735.aspx这个还是比较靠谱的一个,但是它说的释放mic资源根本无法完全释放,会在电话中出现断断续续的情况。但对于使用可以作为一个参照版本,还是不错。
先看看api上的介绍:
public void release ()
Since: API Level 3
Releases the native AudioRecord resources. The object can no longer be used and the reference should be set to null after a call to release()
你一定觉得这个解释非常恼火,起码我觉得是的。根据我使用的结果应该意思是:
释放之后这个对象不能再被使用,而且引用必须变null。像废话,就是翻译嘛,但是意思不仅仅是翻译。
两种最基本的错误方式:
1。在一个线程里面处理录音,然后继承Thread的类中提供方法release,然后电话来之前先stop,然后release。
2。像那个网址里面,但是在run最后加上release。电话来时、或者后台运行时先pause,然后start
据这两个例子,肯定都是错的。先说问题
1。先stop或suspend再release,本质上对于audiorecord的操作还没有结束,只是要求强制关闭(stop方法本身不安全)。还是会继续占用mic,所以释放就会造成线程意外结束,系统报出线程意外中断的错误。这就是the reference should be set to null。虽然来电的情况系统会自动为你再次开启,但是总不至于每次都让用户去看到程序中断吧。
2。先pause掉之后,程序正常隐蔽,但是由于程序还会在start再次调用record,虽然是重新生成一个新的。这就是object can no longer be used and the reference should be set to null。所以在重新回到程序时会抛出相同错误。
这里解决方案已经很明显了,就是在实例程序的run结尾加上ar.release();。 来电结束时重新生成一个新的线程,让原来的线程结束去吧!这样就可以再来电和后台时成功释放mic了,希望解释这两个错误能让你了解那句话和系统抛出的这个纠结的错误。
另外,那个实例有个错误,大家想必看到了吧,还是说一下,网上错误太多了:
public void start() {
// 在调用本线程的 Activity 的 onResume 里调用,以便 Activity 恢复后继续获取麦克风输入音量
if (!isRun) {
super.start();
isRun = true;
}
}
附:很多录音在模拟器是无法测试的,所以请在真机上测试,也所以才有这个纠结的不好找到源头的错误。
private final static int CHANNEL_MODE = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private final static int ENCODING = AudioFormat.ENCODING_PCM_8BIT;
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, RATE,
CHANNEL_MODE, ENCODING, CHUNK_SIZE_IN_SAMPLES * 2);
我记得貌似只支持这个,频率是最低的吧 起码44100不支持,你可以用AudioRecord.getMinBufferSize这个方法测试一下。有个外国的网站上有人统计过,但是找不到了,忘了保存起来了,只能分享这些了,呵呵。好了,就这些