Media start error原因分析及解決方法
之前在專案的時候,遇到到Media Recorder在快速啟動停止等一系列操作的後,再次啟動時,會failed的問題,類似的Log如下:
ERROR/MediaRecorder(9008):
startfailed:-19
WARN/dalvikvm(9008): threadid=15: thread exiting with uncaught exception (group=0x40ad01f8)
ERROR/AndroidRuntime(9008): FATAL EXCEPTION: Thread-337
ERROR/AndroidRuntime(9008): java.lang.RuntimeException: start failed.
ERROR/AndroidRuntime(9008): at android.media.MediaRecorder.start(Native Method)
ERROR/AndroidRuntime(9008): at com.huawei.ca.eivs.camera.AndroidVideo.initMediaRecoder(AndroidVideo.java:429)
ERROR/AndroidRuntime(9008): at com.huawei.ca.eivs.camera.AndroidVideo.sendLiveToMdu(AndroidVideo.java:511)
ERROR/AndroidRuntime(9008): at com.huawei.ca.eivs.camera.AndroidVideo$ListenInviteThread.run(AndroidVideo.java:241)
WARN/ActivityManager(210): Force finishing activity com.huawei.ca.eivs.ui/com.huawei.ca.eivs.camera.AndroidVideo
ERROR/ActivityManager(210): exception bw.write()java.io.IOException: Transport endpoint is not connected
這個時候,退出自己的軟體,開啟系統相機,會提示“相機故障,無法連線到相機”,只能重啟機器才能正常使用系相機。
根據反覆測試抓log發現,造成MediaRecorder start失敗的原因是:在程式中反覆啟動停止MediaRecord時,存在在無效的狀態上stop MediaRecorder的情況,而且沒有捕獲此操作引發的異常,沒有對MediaRecorder進行reset、release造成的。
具體的MediaRecorder狀態遷移,請參看SDK。
解決辦法:
解決這個問題的關鍵是保證MediaRecorder能在合適的狀態執行合適的動作。
下面是我的解決方法,希望能給遇到這個問
</pre>題的人一個靈感:</p><p style="padding-top: 0px; padding-bottom: 0px; margin-top: 0px; margin-bottom: 0px; margin-left: 40px; color: rgb(52, 52, 52); font-family: Simsun; line-height: 24px;"><pre name="code" class="java"><span style="font-family: Simsun;">private void releaseMediaRecorder()</span>
{
if (mMediaRecorder != null)
{
// 內部標識是否正在錄影的變數,如果不需要可以去掉
if (isRecord)
{
try
{
mMediaRecorder.setOnErrorListener(null);
mMediaRecorder.setOnInfoListener(null);
// 停止
mMediaRecorder.stop();
}
catch (RuntimeException e)
{
e.printStackTrace();
// 如果發生異常,很可能是在不合適的狀態執行了stop操作
// 所以等待一會兒
try
{
Thread.sleep(100);
}
catch (InterruptedException e1)
{
Log.e(TAG, "sleep for second stop error!!");
}
}
isRecord = false;
}
// 再次嘗試停止MediaRecorder
try
{
mMediaRecorder.stop();
}
catch (Exception e)
{
Log.e(TAG, "stop fail2", e);
}
// 等待,讓停止徹底執行完畢
try
{
Thread.sleep(100);
}
catch (InterruptedException e1)
{
Log.e("TAG", "sleep for reset error Error", e1);
}
// 然後再進行reset、release
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
}
}