简体   繁体   English

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

[英]NullPointerException while using Android's mediaplayer

I have two button and it will play a sound to notify about right choice, or wrong one.我有两个按钮,它会播放声音来通知正确的选择,或者错误的选择。 This is how I do it:我就是这样做的:

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

Same with correct sound.与正确的声音相同。 It works fine most of the time, but when I click it many times, at random times I get this error:它在大多数情况下都可以正常工作,但是当我多次单击它时,会随机出现此错误:

Basically it says line playError.start();基本上它说 line playError.start(); gives me NullPointerException (only sometimes)给我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)

Edit:编辑:

Line is 148: playError.start();第 148 行:playError.start();

And falseAnswerPoints() is:而 falseAnswerPoints() 是:

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

Same is correctAnswerPoints, but with different sound.同样是正确的答案点,但声音不同。 That's about it.就是这样。 Sometimes it gives NullPointerException with one, sometimes with another...有时它给 NullPointerException 一个,有时另一个......

Answer:回答:

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

It seems the MediaPlayer cannot be created, the create() method returning a null pointer.似乎无法创建MediaPlayercreate()方法返回null指针。 The official doc says this happens when the creation fails, with no further details. 官方文档说创建失败时会发生这种情况,没有进一步的细节。

You said this happens when you click several times in a row on the button that leads this method to be called.您说当您连续多次单击导致调用此方法的按钮时会发生这种情况。 This is probably due to a non reentrancy issue.这可能是由于不可重入问题。

You should try to surround the MediaPlayer creation and usage by a flag that would prevent reentrancy:您应该尝试用一个可以防止重入的标志来包围MediaPlayer的创建和使用:

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

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

mPlayingSound being a private boolean member initialized to false and that you would reset to false once the MediaPlayer would have finished playing (using public void setOnCompletionListener (MediaPlayer.OnCompletionListener listener) should be fine, although I am not sure whether it is called in case of abnormal or anticipated termination of the play). mPlayingSound是一个private boolean成员,初始化为false ,一旦MediaPlayer完成播放,您将重置为false (使用public void setOnCompletionListener (MediaPlayer.OnCompletionListener listener)应该没问题,尽管我不确定是否在以下情况下调用它比赛的异常或预期终止)。

EDIT : There is a NullPointerException so there is a stack trace.编辑:有一个 NullPointerException 所以有一个堆栈跟踪。 To capture the stack trace, in debug only (the code below is not suitable for release), you can do as follows:要捕获堆栈跟踪,仅在调试中(下面的代码不适合发布),您可以执行以下操作:

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.
    }
}

I'm afraid all answers here are wrong.恐怕这里的所有答案都是错误的。 I encountered this issue, albeit more than a year later, but after some research found the answer.我遇到了这个问题,虽然是在一年多之后,但经过一番研究找到了答案。 It's in two parts.它分为两部分。

  1. Best to start the mediaplayer AFTER the declaration of the onCompleteListener.最好在声明 onCompleteListener 之后启动媒体播放器。 This insures that the mediaplayer has a full list of instructions declared before it even start playing.这确保了媒体播放器在开始播放之前就已经声明了完整的指令列表。
  2. Use a statically declared object called an AtomicBoolean.使用称为 AtomicBoolean 的静态声明的 object。 This insures that there is only one boolean parameter, and that the process is locked until it finishes the process.这确保了只有一个 boolean 参数,并且进程被锁定直到它完成进程。 This is the only way to insure a process is thread safe.这是确保进程是线程安全的唯一方法。

Hope you found this useful (all future programmers that encounter this problem);-)希望您发现这很有用(所有未来遇到此问题的程序员);-)

To solve your problem you can try to write a permission <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />要解决您的问题,您可以尝试编写权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

in manifest在清单中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM