使用Android的媒体播放器时出现NullPointerException

我有两个按钮,它会发出声音来通知正确的选择,或者错误的选择。 我是这样做的:

MediaPlayer playError = MediaPlayer.create(QuizActivity.this, R.raw.error); playError.start(); 

与正确的声音相同。 它在大多数情况下工作正常,但当我多次点击它时,随机时间我得到这个错误:

基本上它说行playError.start(); 给我NullPointerException (有时只)

 07-21 23:05:32.767: ERROR/PlayerDriver(1287): Command PLAYER_PREPARE completed with an error or info PVMFErrResource, -17 07-21 23:05:32.767: ERROR/MediaPlayer(14449): error (1, -17) 07-21 23:05:32.767: ERROR/MediaPlayer(14449): MEDIA_ERROR(mPrepareSync) signal application thread 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): FATAL EXCEPTION: main 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): java.lang.NullPointerException 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at com.quiz.QuizActivity.falseAnswerPoints(QuizActivity.java:148) 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at com.quiz.QuizActivity$5.onClick(QuizActivity.java:86) 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at android.view.View.performClick(View.java:2408) 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at android.view.View$PerformClick.run(View.java:8816) 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at android.os.Handler.handleCallback(Handler.java:587) 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at android.os.Handler.dispatchMessage(Handler.java:92) 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at android.os.Looper.loop(Looper.java:123) 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at android.app.ActivityThread.main(ActivityThread.java:4627) 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at java.lang.reflect.Method.invokeNative(Native Method) 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at java.lang.reflect.Method.invoke(Method.java:521) 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 07-21 23:05:32.777: ERROR/AndroidRuntime(14449): at dalvik.system.NativeStart.main(Native Method) 

编辑:

Line是148:playError.start();

而falseAnswerPoints()是:

 public void falseAnswerPoints() { MediaPlayer playError = MediaPlayer.create(QuizActivity.this, R.raw.error); playError.start(); } 

同样是correctAnswerPoints,但声音不同。 就是这样。 有时候它给NullPointerException一个,有时候另一个……

回答:

 MediaPlayer playSuccess = MediaPlayer.create(QuizActivity.this, R.raw.success); playSuccess.start(); playSuccess.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer playSuccess) { playSuccess.release(); } }); 

似乎无法创建MediaPlayercreate()方法返回null指针。 官方文档称这种情况发生在创建失败时,没有进一步的细节。

你说当你在按钮上连续多次点击导致调用此方法时会发生这种情况。 这可能是由于非重入问题。

您应该尝试通过防止重入的标志来围绕MediaPlayer创建和使用:

 public void falseAnswerPoints() { if (!mPlayingSound) { mPlayingSound = true; MediaPlayer playError = MediaPlayer.create(QuizActivity.this, R.raw.error); playError.start(); } } 

mPlayingSound是一个初始化为falseprivate boolean成员,一旦MediaPlayer完成播放你就会重置为false (使用public void setOnCompletionListener (MediaPlayer.OnCompletionListener listener)应该没问题,虽然我不确定它是否被调用)该剧的exception或预期终止)。

编辑 :有一个NullPointerException,所以有一个堆栈跟踪。 要捕获堆栈跟踪,仅在调试中(下面的代码不适合发布),您可以执行以下操作:

 public void falseAnswerPoints() { try { MediaPlayer playError = MediaPlayer.create(QuizActivity.this, R.raw.error); playError.start(); } catch (NullPointerException e) { // Set a breakpoint there to inspect the state of your app // Then rethrow the exception to have it logged, and why not // log extra info. } } 

我担心这里的所有答案都是错的。 我遇到了这个问题,虽然超过一年后,但经过一些研究后找到了答案。 它分为两部分。

  1. 最好在声明onCompleteListener之后启动媒体播放器。 这可以确保媒体播放器在开始播放之前已经声明了完整的指令列表。
  2. 使用名为AtomicBoolean的静态声明对象。 这确保了只有一个布尔参数,并且该进程在完成该进程之前一直处于锁定状态。 这是确保进程是线程安全的唯一方法。

希望你发现这很有用(所有未来遇到这个问题的程序员);-)

要解决您的问题,您可以尝试编写权限

在清单中