Android 使用MediaRecorder錄音調用stop()方法的時候報錯【轉】

來源:互聯網
上載者:User

標籤:cfile   無法   view   hat   encode   message   順序   cli   stat   

本文轉載自:http://blog.csdn.net/u014737138/article/details/49738827

這個問題在網上看到了太多的答案,一直提示說按照官網的api的順序來,其實解決問題的方法不是這樣的,那樣沒法解決問題,照著那個順序來也米有用

 

我們得知道為什麼它停止不了,為什麼停止閃退了,

 

這裡面有個結論就是:閃退必然是出現了控制值的錯誤,在Java中就是java.lang.NullXXException的錯誤

 

好像沒有其他的原因導致閃退把,

 

stop 就刪除,是因為stop的對象不存在,這個懂把,

stop對象不存在,說明對象new失敗,這個懂吧,

stop的對象new失敗,那就需要看new執行了哪些操作了:

 

[java] view plain copy 
  1. <strong><span style="font-size:18px;">mr=new MediaRecorder();  
  2. mr.setAudioSource(MediaRecorder.AudioSource.MIC);  
  3. mr.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);  
  4. mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  
  5. mr.setMaxDuration(10000);  
  6. mr.setOutputFile(Environment.getExternalStorageDirectory().getPath()+File.separator+"fisii77s.3gp");  
  7. mr.prepare();  
  8. mr.start();</span></strong>  


我相信大家都是這樣的做法,關鍵是我們前麵包了一層if(mr==null)的判斷了

 

我在代碼中報錯之前是這樣寫的:

 

[java] view plain copy 
  1. <strong><span style="font-size:18px;">  public void start(Context context, String name) {  
  2.         if (!Environment.getExternalStorageState().equals(  
  3.                 android.os.Environment.MEDIA_MOUNTED)) {  
  4.             return;  
  5.         }  
  6.         if (mRecorder == null) {  
  7.             mRecorder = new MediaRecorder();  
  8.             mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  
  9.             mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);  
  10.             mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  
  11.             mRecorder.setOutputFile(UtilsForChat.getMusicFilePath(context, name));  
  12.             try {  
  13.                 mRecorder.prepare();  
  14.                 mRecorder.start();  
  15.   
  16.                 mEMA = 0.0;  
  17.             } catch (IllegalStateException e) {  
  18.                 System.out.print(e.getMessage());  
  19.             } catch (IOException e) {  
  20.                 System.out.print(e.getMessage());  
  21.             }  
  22.   
  23.         }  
  24. }</span></strong>  

也就是說如果對象存在,沒有被銷毀掉,我就不用建立了,按照常理說,確實應該這樣判斷對吧,可是常理一般都是錯誤的,

 

在java中 判斷 一個對象是否為空白確實是 == null  關鍵是 ==null是有誰來判斷的  這個好像是說面試的時候經常這樣考   我這裡還是講講我一直那麼理解的東西啊,本人還在讀書,希望對以後找工作面試的時候有用 哈哈

== 這個判斷是地址值比較的,equals是內容值比較的

== 這個地址值是指堆記憶體的,equals這個值是指在棧記憶體中的

 

在我們知道null判斷的機制的了之後,我們就要去考慮,如果這個對象還存在,我們是否能直接用這個對象呢,經過測試答案是不行的,

 

接下來再接著說,如果我們第一次建立一個MediaRecorder對象,當我們錄音結束之後肯定是停止並且釋放了的,否則錄音檔案就不成功了,

停止,停止的是jni對象,釋放,釋放的jni裡面的對象,同時也釋放了java對象裡面的棧記憶體的值,堆記憶體還保留著呢,引用為空白   這裡搞明白了,原因也就出來了,

關於這裡面jni機制如果不懂,可以看我上篇文章,講解的很詳細

釋放之後,如果馬上執行第二次錄音,這個時候上面的if代碼就需要判斷了,很明顯if裡面的語句是不會被執行的,因為堆記憶體沒有被釋放掉啊,但是jni裡面的對象全部被釋放掉了

 

這個時候如果你還用這個對象去錄音,那麼結果就是你對著空氣說話,錄的音也成了空氣,然後你鬆開手指也就是錄音對象停止的時候,無法停止了,因為jni對象是空的,不存在,怎麼去停止呢,程式直接閃退,原因就是這樣的了

 

解決辦法就是這個時候如果你的對象不為空白,你需要再重新建立一次,主要是保證你錄音不會成為空白氣,

 

 

[java] view plain copy 
  1. <strong><span style="font-size:18px;">  public void start(Context context, String name) {  
  2.         if (!Environment.getExternalStorageState().equals(  
  3.                 android.os.Environment.MEDIA_MOUNTED)) {  
  4.             return;  
  5.         }  
  6.         if (mRecorder == null) {  
  7.             mRecorder = new MediaRecorder();  
  8.             mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  
  9.             mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);  
  10.             mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  
  11.             mRecorder.setOutputFile(UtilsForChat.getMusicFilePath(context, name));  
  12.             try {  
  13.                 mRecorder.prepare();  
  14.                 mRecorder.start();  
  15.   
  16.                 mEMA = 0.0;  
  17.             } catch (IllegalStateException e) {  
  18.                 System.out.print(e.getMessage());  
  19.             } catch (IOException e) {  
  20.                 System.out.print(e.getMessage());  
  21.             }  
  22.   
  23.         }else{  
  24.             stop();  
  25.             mRecorder = new MediaRecorder();  
  26.             mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  
  27.             mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);  
  28.             mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  
  29.             mRecorder.setOutputFile(UtilsForChat.getMusicFilePath(context, name));  
  30.             try {  
  31.                 mRecorder.prepare();  
  32.             } catch (IllegalStateException | IOException e) {  
  33.                 // TODO Auto-generated catch block  
  34.                 e.printStackTrace();  
  35.             }  
  36.             mRecorder.start();  
  37.         }  
  38.     }</span></strong>  


代碼就變成這樣了,其實,這裡面更簡單點就是每次不判斷,進來直接把原來的停止,然後再建立 可以省掉很多代碼了

 

 

然後就是stop函數,一定要寫對,否則還是報錯的哦:

 

 

[java] view plain copy 
  1. <strong><span style="font-size:18px;">  public void stop() {  
  2.         if (mRecorder != null) {  
  3.             try {  
  4.                 mRecorder.stop();  
  5.             } catch (IllegalStateException e) {  
  6.                 // TODO 如果當前java狀態和jni裡面的狀態不一致,  
  7.                 //e.printStackTrace();  
  8.                 mRecorder = null;  
  9.                 mRecorder = new MediaRecorder();  
  10.             }  
  11.             mRecorder.release();  
  12.             mRecorder = null;  
  13.         }  
  14.     }</span></strong>  


這裡面有人肯定問,你這裡面stop已經搞了異常拋出,為什麼上面的建立還加上else那樣的代碼呢,

 

 

這裡面也是機型的原因然後導致我最終還是保留了這段代碼   因為要保證你說的話,錄音的音不會成為空白氣啊  這也是很重要的bug啊

Android 使用MediaRecorder錄音調用stop()方法的時候報錯【轉】

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.