簡體   English   中英

android MediaPlayer NullPointerException

[英]android MediaPlayer NullPointerException

我有點難以對此進行故障排除,因為我是通過其他人的Android設備的崩潰報告得到的,我無法向他們提問,而且我從未在自己的Android設備上看到它。

崩潰報告說它是Android 4.1.2,堆棧跟蹤是:

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)

不幸的是,grepcode.com上的android源代碼似乎與這些行號不匹配,所以我不確定哪個是null。

當發生這種情況時,我不知道用戶正在做什么,所以我不知道這是在音樂或聲音效果正在播放時發生,還是在發生破壞時發生了什么。 我有點懷疑它可能在毀滅期間發生。 我在activity的onDestroy方法中有以下代碼:

public void onDestroy() {
    synchronized(curPlayers) {
        for(List<MediaP> ms : curPlayers.values()) {
            synchronized(ms) {
                for(MediaP m : ms) {
                    synchronized(m) {
                        m.m.stop();
                        m.m.release();
                    }
                }
            }
        }
        curPlayers.clear();
    }
}

private static class MediaP {
    private MediaP(MediaPlayer m) {
        this.m = m;
    }

    private MediaPlayer m;
    private boolean wasPlaying = false;
}

那里有什么我應該做的嗎?

release()之前刪除對MediaPlayer.stop()的調用。 我們在Nexus 4,5,7,10和Moto X上看到了很多類似的崩潰。你可以在MediaPlayer $ EventHandler.handleMessage中閱讀更多NullPointerException

據我所知,有一次他們切換到從stop()發送消息,如果你不夠運氣,你的release()會在檢查到它不為空並嘗試調用其方法后立即使對象無效。

漢克和德米特里幾乎沒有這個,但最好采用綜合方法。

競爭條件介於Android KitKat和Lollipop版本上的內部MediaPlayer事件處理程序和reset()/ release()之間。 release()使用所有事件處理程序(例如onCompletion)創建競爭條件,而reset()僅具有回放狀態消息的競爭。 (start(),pause(),stop(),onCompletion(),onInfo()也發布內部回放狀態消息)。 如果在空檢查之后但在取消引用之前處理這些消息時調用了reset()/ release(),則會發生NPE。

為避免這種情況,您可以:

  1. 永遠不要調用reset()或release()。 這是不可接受的,因為必須釋放每個MediaPlayer對象()。
  2. 只從事件處理程序調用reset()或release()(例如onCompletion,onError等)。 這可以避免競爭,但是它本身是不可接受的,因為您可能需要在事件之外調用reset()/ release()。
  3. 在事件之外調用reset()/ release()時,如果媒體播放器沒有停止(例如播放或暫停)以調用內部消息和已知的穩定狀態,則調用stop(),然后等待一些例如50毫秒,然后再調用release ()。 這基本上是漢克的建議。

最好的方法是2和3的組合。

代替

release()之前刪除對MediaPlayer.stop()的調用

我在release()之前添加了一個Thread.sleep(50) release()並解決了這個異常。 似乎不僅stop()會被release()的無效所困擾,其他一些像OnCompletionListener這樣的事件處理程序也會OnCompletionListener這個問題。

鑒於您的具體情況,我認為目標設備可能正在運行自制的固件映像。

媒體播放器可能是自定義的,未正確編程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM