Android MediaPlayer NullPointerException

Itโ€™s a little difficult for me to fix this, because I get it through a crash report from another Android device, I have no way to ask them questions, and I have never seen this happen on my own Android devices.

Crash reports say Android 4.1.2 and stack trace:

java.lang.NullPointerException at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:2102) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5021) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556) at dalvik.system.NativeStart.main(Native Method) 

Unfortunately, the Android source code on grepcode.com does not seem to match these line numbers, so I'm not sure which thing is zero.

I donโ€™t know what the user did when this happens, so I donโ€™t know if this happens when playing music or sound effects, or if it happens when being destroyed or something like that. I seem to suspect that this could happen during the destruction. I have the following code in the onDestroy method:

 public void onDestroy() { synchronized(curPlayers) { for(List<MediaP> ms : curPlayers.values()) { synchronized(ms) { for(MediaP m : ms) { synchronized(m) { mmstop(); mmrelease(); } } } } curPlayers.clear(); } } private static class MediaP { private MediaP(MediaPlayer m) { this.m = m; } private MediaPlayer m; private boolean wasPlaying = false; } 

Is there something out there that I have to do?

+4
source share
4 answers

Remove the call to MediaPlayer.stop() before release() . We have seen many similar crashes on Nexus 4, 5, 7, 10 and Moto X. Here you can read here the NullPointerException in MediaPlayer $ EventHandler.handleMessage

As I understand it, at some point they switched to sending messages from stop() , and if you are not lucky, your release() will invalidate the object immediately after it checks that it is not null and tries to call its method.

+4
source

For Hank and Dmitry, this is almost correct, but it is best to use a combined approach.

The race condition is between the internal MediaPlayer event handler and reset () / release () in Android KitKat and Lollipop versions. release () creates a race condition with all event handlers (for example, onCompletion), and reset () only has a race with playback status messages. (start (), pause (), stop (), onCompletion (), onInfo () also report internal playback status). NPE occurs if reset () / release () is called when this message is processed after zero checks, but before dereferencing.

To avoid this, you can:

  • never call reset () or release (). This is unacceptable since each MediaPlayer object must be freed ().
  • only call reset () or release () from the event handler (e.g. onCompletion, onError, etc.). This avoids the race, but in itself is unacceptable, as you may need to call reset () / release () outside the event.
  • When reset () / release () is called outside the event, call stop () if the media player is not stopped (for example, play or pause) to cause an internal message and a known stable state, and then wait for some, for example, 50 ms before calling release (). This is basically Hank's suggestion.

The best approach is a combination of 2 and 3.

+2
source

Instead

Delete call MediaPlayer.stop() to release()

I add Thread.sleep(50) to release() and eliminate this exception. It seems that not only stop() will worry about canceling release() , but other event handlers like OnCompletionListener .

+1
source

Given your specific situation, I think that the target device can work with a home-made firmware image.

The media player may be configured and incorrectly programmed.

0
source

Source: https://habr.com/ru/post/1496960/


All Articles