MediaRecorder(java.lang.RuntimeException: stop failed.)

Posted by ITPangPang
2016. 12. 31. 14:30 안드로이드 에러/RuntimeException


MediaRecorder

(java.lang.RuntimeException: stop failed.)





ㆍMediaRecorder를 이용하여 녹음을 할때 발생하는 에러.


ㆍ위 에러는 녹음을 시작하고 mediaRecorder.stop()을

   하는순간 일어난다.



좀 더 자세히보면

java.lang.RuntimeException: stop failed.

at android.media.MediaRecorder._stop(Native Method)

at android.media.MediaRecorder.stop(MediaRecorder.java:976)


뭐 이런식으로 나온다.



Stop을 누를때 에러가 발생하는 원인은

Reference를 보면 알 수 있다.


참고 :

https://developer.android.com/reference/android/media/MediaRecorder.html#stop()



정확한 해석은 아니더라도

대충 읽어보면,


위 에러가 발생하는 이유는

start 후에 stop을 너무 빨리 호출했을 경우이다.


저도 기능구현을 할때까지는

몰랐었는데.


대부분 개발자들이 그렇듯

이제 테스트로 넘어가면


손가락으로 모든 버튼을

다다다다다다닥 마구잡이로 누르면서

테스트 하게 되는데


여기서 저도 에러가 발생해서 알게되었습니다.


start -> stop -> start -> stop 무한테스트


조금 더 정확한 원인은 start 하게 될때

setDataSource에 녹음을 하게 될 경로를 적게 되는데

여기서 엄청 빠르게 경로를 찾겠지만

그래도 살짝의 준비시간은 필요한 것 같다.


이 준비가 되기전에 stop을 바로 눌러버리면

발생해버리는 것 같다.


이제 해결방법을 알아보면


해결방법


해결방법을 알아보려고 했는데

아에 막아버릴 방법은 없는 것 같다.


그래서


첫번째,

start를 누른후에 약 1초이내로는

stop 버튼을 못누르게 막는다.

(start 1초후 stop 버튼

비활성화 -> 활성화 변경)


위와 비슷하게 버튼 비활성화가 아닌

Toast나 SnackBar를 띄워줘도 된다.




두번째,

대부분 이 방법을 사용할 것이다.

그냥 try ~ catch로 막아버린다.

try
{
mediaRecorder.stop();
}
catch (RuntimeException e)
{
//exception 처리
}


이렇게 넣어버리면

에러 발생시 catch로 빠지게 된다.


여기서 한가지만 더 적으면

원래 stop 처리를

mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;


이렇게 해버렸었는데


이렇게 release(메모리해제)

까지 같이 해버리면


try~catch를 쓰더라도

앱이 죽게 된다.


그래서 release는 빼고 위에처럼

사용하고, 녹음이 완전히 끝나는 시점에

release를 해주면 된다.


그렇다면 예외처리??


이거야 뭐 앱마다 다르겠지만.


제가 만들고 있는 프로젝트 상황에서

 예외처리를 하나 적어보자면.


저는 녹음 start를 할때

List에 파일경로를 담습니다.

(파일 병합을 위해서..)


일시정지 기능을 넣다보니

start 누를때 List.add(경로)로 담고

stop때 일시정지

다시 start 누를때 List.add(두번째파일 경로)


이렇게 하고 녹음이 끝날때

리스트에 담겨있는 파일경로로 접근해서

파일들을 합치는 작업을 합니다.


그런데 위와 같이 try catch로 묶어서

catch로 빠지는 순간이 있게 되면


start, stop을 5번 할 경우(5개의 파일 생성)

파일1 : 에러x

파일2 : 에러x

파일3 : catch(에러o)

파일4 : 에러x

파일5 : 에러x


이렇게 되면 파일3에 문제가 있기때문에

파일을 합치는 과정에서 문제가 생깁니다.


그래서 이를 처리하기 위해

만약 catch로 빠지는 경우에서는

List에서 에러나는 파일경로를 빼줘야 합니다

catch (RuntimeException e)
{
//exception 처리
audioFileList.remove(audioFileList.size()-1);
}



이런식으로 상황에 맞게

예외처리를 해주시면 됩니다.