android中java.lang.IllegalStateException异常产生的原因及解决办法

原文地址:https://blog.csdn.net/u014737138/article/details/49737955

[java]  view plain  copy
  1. 11-09 13:33:56.080: E/MediaRecorder(19865): stop called in an invalid state: 0  
  2. 11-09 13:33:56.080: I/MediaRecorder(19865): stop  
  3. 11-09 13:33:56.080: E/MediaRecorder(19865): stop called in an invalid state: 1  
  4. 11-09 13:33:56.080: E/InputEventReceiver(19865): Exception dispatching input event.  
  5. 11-09 13:33:56.080: E/MessageQueue-JNI(19865): Exception in MessageQueue callback: handleReceiveCallback  
  6. 11-09 13:33:56.080: E/MessageQueue-JNI(19865): java.lang.IllegalStateException  
  7. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.media.MediaRecorder.native_stop(Native Method)  
  8. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.media.MediaRecorder.stop(MediaRecorder.java:1127)  
  9. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at com.jarvis.message.SoundMeter.stop(SoundMeter.java:64)  
  10. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at com.jarvis.message.SoundMeter.start(SoundMeter.java:38)  
  11. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at com.jarvis.user.RusumeReadView.start(RusumeReadView.java:522)  
  12. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at com.jarvis.user.RusumeReadView.access$26(RusumeReadView.java:520)  
  13. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at com.jarvis.user.RusumeReadView$17.onTouch(RusumeReadView.java:469)  
  14. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.View.dispatchTouchEvent(View.java:8287)  
  15. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  16. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  17. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  18. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  19. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  20. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  21. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  22. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  23. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  24. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  25. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  26. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  27. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  28. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  29. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  30. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  31. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  32. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  33. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  34. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  35. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  36. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  37. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  38. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  39. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2324)  
  40. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2011)  
  41. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2345)  
  42. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1708)  
  43. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.app.Activity.dispatchTouchEvent(Activity.java:2797)  
  44. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2306)  
  45. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.View.dispatchPointerEvent(View.java:8483)  
  46. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4291)  
  47. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4157)  
  48. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3662)  
  49. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3715)  
  50. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3681)  
  51. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3791)  
  52. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3689)  
  53. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3848)  
  54. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3662)  
  55. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3715)  
  56. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3681)  
  57. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3689)  
  58. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3662)  
  59. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5978)  
  60. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5952)  
  61. 11-09 13:33:56.080: E/MessageQueue-JNI(19865):  at android.view.ViewRootImpl.enqueueInputEvent(ViewRootIm  


出现这个问题真的很难受,搞了好久,其实不同的机型有不同的效果,我在魅族 手机 华硕手机  华为p8上都没有出现这样的问题

在小米2s 在华为荣耀7 上都出现了这样的bug  


接下来是分析真正的问题原因所在 解决办法很简单,就是捕获这个异常,因为是空的,再重新new下,然后接着释放就可以了

IllegalStateException这个异常它是指“非法的状态”。

android的MediaRecorder 和MediaPlayer API中用到了JNI,也就是我们的java代码是要调用native的C++方法的

MediaRecorder ,MediaPlayer 是用c++实现的),

出现这个异常,就是因为我们java里面的MediaRecorder ,MediaPlayer 对象的状态和native的对象状态发生了不一致。


问题的本质就是这样的,那什么叫状态不一致,我们得用代码中来解析下才能看的懂了:


使用的时候我们应该都知道,MediaRecorder 和MediaPlayer 用的方法有哪些了

[java]  view plain  copy
  1. if (mMediaPlayer.isPlaying()) {  
  2.                 mMediaPlayer.stop();  
  3.             }  
  4.             mMediaPlayer.reset();  
  5.             mMediaPlayer.setDataSource(name);  
  6.             mMediaPlayer.prepare();  
  7.             mMediaPlayer.start();  

[java]  view plain  copy
  1. if (mRecorder == null) {  
  2.     mRecorder = new MediaRecorder();  
  3.     mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  
  4.     mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);  
  5.     mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  
  6.     mRecorder.setOutputFile(UtilsForChat.getMusicFilePath(context, name));  
  7.     try {  
  8.         mRecorder.prepare();  
  9.         mRecorder.start();  
  10.   
  11.         mEMA = 0.0;  
  12.     } catch (IllegalStateException e) {  
  13.         System.out.print(e.getMessage());  
  14.     } catch (IOException e) {  
  15.         System.out.print(e.getMessage());  
  16.     }  
  17.   
  18. }  
mRecorder.stop();
mRecorder.release();

我相信大家都对这些方法都不陌生的,只是需要我们知道他们的顺序,但是仅仅知道顺序肯定是没有用的,

因为你照样会产生上面的错误  比如专业的错误:

切换录像暂停过快导致stop failed.
java.lang.RuntimeException: stop failed.
at android.media.MediaRecorder.stop(Native Method)

原因如下:
在调用start()后马上调用stop(),时由于没有生成有效的音频或是视频数据。解决方法:让线程睡眠一定的时间,在测试后发现1秒几乎是最短时间。

猜你喜欢

转载自blog.csdn.net/dodod2012/article/details/80481986