【问题标题】:Android Media Player hanging or returning nullAndroid 媒体播放器挂起或返回 null
【发布时间】:2011-11-26 23:48:27
【问题描述】:

我遇到了一个关于 android MediaPlayer 的有趣情况。我有大约 30 种声音需要在活动中播放。我得到奇怪的结果,我不确定是否来自内存问题......

我需要使用媒体播放器的原因是我有一个定时流到一个声音需要以特定顺序在另一个声音之后播放的声音。我还使用回调来查看接下来播放的声音。这样,soundpool 就出来了……

我尝试使用 MediaPlayer.create() 将每个声音加载到它自己的媒体播放器中。现在,这在我的设备三星 Galaxy S Vibrant 上运行良好。我的客户使用三星 Ace,但是当我尝试设置 onCompletionListener 时出现空指针异常,这意味着 .create() 在他的设备上返回 null 而不是我的。

所以,我从一次加载它们切换到在上一个声音 using this method 的 onCompletionListener 中动态加载它们

这种作品,拳头 3-4 声音播放然后它挂在我客户的设备上(在我的设备上仍然可以正常工作)。我假设它挂在 .prepare()

这很难解决,因为我的客户对 logcat 没有真正的了解,也没有要调试的 SDK,而且它在我的设备上运行良好。它甚至挂在他的第二台设备上,该设备与我的型号相同。

有人知道是什么原因造成的或如何调试它吗?

我想我的下一步将是简单地使用一个 MediaPlayer 并使用 OnCompletionListener 的 mp 参数在同一个媒体播放器上加载下一个声音。我会发布我的发现。

【问题讨论】:

    标签: android memory-management media-player


    【解决方案1】:

    如果您正确释放媒体播放器,则应该不是内存问题。您可以通过以下方式正确确保这一点:

    if(mediaplayer!=null){
            if(mediaplayer.isPlaying()){
                mediaplayer.stop();
            }
            mediaplayer.release();
            mediaplayer = null;
    }
    

    我相信 apk 内存分配有 10MB 的限制(最低限度,有些手机更高),所以您应该能够检查这是否符合您的限制。但是,市场最多允许 50MB。

    对于调试,我建议您确保所有的资产都在那里(听起来很傻,但它排除了它),因为如果您丢失了声音文件,它当然会无法创建。如果抛出异常,则创建 Toast 通知,例如IllegalStateException 将确保您管理媒体播放器状态不成问题。

    还值得一提的是,您永远不应该混合使用 preparecreate。如果您正在使用create,它已经调用prepare 并且随后调用prepare 可能会导致奇怪的行为;不确定它是否会使玩家无效!

    一般来说,您并不想真正按照您建议的方式进行操作(创建一个新的媒体播放器并更改onComplete 中的声音)。原因很简单,当您调用createprepare 时,它会将声音加载到内存中——这将花费不同的时间,具体取决于手机(对于某些手机来说可能需要很长时间!) .一次加载它们要好得多。

    【讨论】:

    • 感谢您的基本检查。我知道有时最简单的解决方案可能是正确的。但不是在这种情况下:) 我没有混合创建和准备。我尝试全部创建它们,最终在某个时候从 .create() 给我一个空返回。
    • 感谢您的帮助,我的方法最终奏效并将其发布为答案,不过我有你 +1。
    【解决方案2】:

    所以,一定是某种内存问题。我最初加载了 20 多个媒体播放器。

    现在我将它们全部组合到一个媒体播放器中并动态加载声音。声音很小,所以我不担心加载时间。

    这里有一些帮助代码,以防有人需要。

    private MediaPlayer getMediaPlayer(MediaPlayer mp, int resID, OnCompletionListener listener){
    mp.release();
    mp = null;
    mp = new MediaPlayer();
    AssetFileDescriptor afd = getResources().openRawResourceFd(resID);
    try {
        mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
        mp.prepare();
        mp.setOnCompletionListener(listener);
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return mp;
    }
    

    我用它来加载新的声音。它有相当多的开销,但它确实有效,这很重要。

    这是我的使用方法。

    mSoundPlayer = getMediaPlayer(mSoundPlayer, R.raw.a123switch, endSwitch123Listener);
    mSoundPlayer.start();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-02
      • 1970-01-01
      • 2012-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多