【问题标题】:NullPointerException while using Android's mediaplayer使用 Android 的媒体播放器时出现 NullPointerException
【发布时间】:2014-06-30 23:29:03
【问题描述】:

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

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)

编辑:

第 148 行:playError.start();

而 falseAnswerPoints() 是:

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

相同的是正确的AnswerPoints,但声音不同。就是这样。有时它给 NullPointerException 一个,有时另一个......

答案:

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

【问题讨论】:

  • 能否发下相关代码?
  • 你能把 QuizActivity.java 的方法 falseAnswerPoints() 贴出来,告诉我们哪一行是 148 吗?
  • @Shlublu 我更新了我的问题...
  • @Badr_Hari 谢谢!我已经在下面回复了。

标签: java android media-player


【解决方案1】:

似乎无法创建MediaPlayercreate() 方法返回一个null 指针。 official doc 表示创建失败时会发生这种情况,没有进一步的细节。

您说当您连续多次单击导致调用此方法的按钮时会发生这种情况。这可能是由于不可重入问题。

您应该尝试将MediaPlayer 的创建和使用用一个可以防止重入的标志包围起来:

public void falseAnswerPoints() {
    if (!mPlayingSound) {
        mPlayingSound = true;

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

mPlayingSound 作为private boolean 成员初始化为false,并且一旦MediaPlayer 完成播放,您将重置为false(使用public void setOnCompletionListener (MediaPlayer.OnCompletionListener listener) 应该没问题,尽管我不确定是否在播放异常或预期终止的情况下调用它。

编辑: 有一个 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.
    }
}

【讨论】:

  • 我已经做过类似的事情,但这似乎不起作用。仅在使用手机调试应用程序时出现错误。我目前只有一部 Android 手机可供测试。使用模拟器我无法重现错误...
  • 在这种情况下,我建议设置一个条件断点,该断点将在 playError 为空时起作用。您是否设法使该错误 100% 可重现(例如“连续单击 10 次”或类似的情况)?
  • 是的,可以通过单击行中的内容来重现该错误。不管多快...但通常大约 10 次点击。它并不总是相同的数字。现在我也能用模拟器得到同样的错误。使用模拟器它也会给我这样的错误:07-21 20:39:24.770: ERROR/AudioService(67): Media server dead。 07-21 20:39:28.890:错误/音频服务(67):媒体服务器已启动。我也试过 try catch 来寻找一个例外,但它没有给我任何东西......但是感谢我思考我的问题,Shlubu ☺
  • 不客气!这种问题很烦人。由于存在 NullPointerEXception,因此存在堆栈跟踪。我在上面编辑了我的答案,以提出一种捕获它并同时检查应用程序状态的方法。
  • 再次感谢您,Shlublu,感谢您的想法,我得到了它的工作...我正在使用 MediaPlayer.OnCompletionListener 来实现音频,这似乎可以解决问题。我将代码添加到我的问题中......
【解决方案2】:

恐怕这里的所有答案都是错误的。我遇到了这个问题,虽然是在一年多之后,但经过一番研究找到了答案。它分为两部分。

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

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

【讨论】:

    【解决方案3】:

    为了解决您的问题,您可以尝试写一个权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    在清单中

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      • 2012-01-22
      • 1970-01-01
      • 2020-02-17
      • 1970-01-01
      • 2012-03-16
      相关资源
      最近更新 更多