Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Mediaplayer过早切断声音_Android_Android Mediaplayer - Fatal编程技术网

Android Mediaplayer过早切断声音

Android Mediaplayer过早切断声音,android,android-mediaplayer,Android,Android Mediaplayer,我有两台设备可以测试我的游戏:一台美国手机(SCH-R880)和一台KindleFire,KindleFire比手机强大得多 我有几个短(小于或大约1秒)的音效。为了节省内存,我加载、播放并释放这些音效。在电话上,他们(大部分)按预期玩。然而,在KindleFire上,它们被切断了。很短的声音很快就被切断了,我什么也听不到。但是,在设置时加载并保留的那些可以正常播放 有人知道这是怎么回事吗?我是不是太快就发布了我的媒体?下面是一个例子。在电话里我听到“第二级”,但在Kindle上我听到类似“Le

我有两台设备可以测试我的游戏:一台美国手机(SCH-R880)和一台KindleFire,KindleFire比手机强大得多

我有几个短(小于或大约1秒)的音效。为了节省内存,我加载、播放并释放这些音效。在电话上,他们(大部分)按预期玩。然而,在KindleFire上,它们被切断了。很短的声音很快就被切断了,我什么也听不到。但是,在设置时加载并保留的那些可以正常播放

有人知道这是怎么回事吗?我是不是太快就发布了我的媒体?下面是一个例子。在电话里我听到“第二级”,但在Kindle上我听到类似“Lev tw”的声音

为了解决这个问题,我尝试了SoundPool,但它不起作用;我什么也没听到。以下是我尝试使用SoundPool播放音乐时所做的操作:

SoundPool soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 100);
    soundPool.load(contxt, R.raw.song2, 1);
    AudioManager mgr = (AudioManager)contxt.getSystemService(Context.AUDIO_SERVICE);
    float streamVolumeCurrent = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
    float streamVolumeMax = mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
    float volume =  streamVolumeMax;  

    soundPool.play(1, volume, volume, 1, 5, 2);
更新

我注意到应该播放(但不播放)的声音出现以下错误:

AudioPolicyManager: stopOutput() oldDevice 2
AudioPolicyManager: [getDeviceForStrategy] strategy : 0,forceUse(0)

我读到SoundPool类比MediaPlayer更适合这样的短声音,但这可能不是问题所在

您还可以发布单击处理程序的代码吗

另外,我建议不要释放和重新获取MediaPlayer实例,而是使用一个MediaPlayer实例,并在需要重用时遵循典型的reset()、setDataSource()、prepare()、start()序列。这将比每次构造一个新实例更有效。i、 e:

MediaPlayer mp = new MediaPlayer();
AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.sound1);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength();
mp.prepare();
mp.start();

//to reuse
mp.reset();
afd = getResources().openRawResourceFd(R.raw.sound2);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength();
mp.prepare();
mp.start();

这很奇怪,而且不是一个好的解决方案,但是迄今为止我找到的唯一解决方案。如果我删除了
mp.setOnPreparedListener
mp.setOnCompletionListener
并且只有
mp.start()
,它就可以工作。

我在一个项目中也遇到了同样的问题,因为在KindleFire中,声音在完成之前就被切断了,所以为了解决这个问题(在发布时),我在发布中增加了一个延迟:

    mpNum.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
    {
        public void onCompletion(MediaPlayer mp)
        {
            // Add a handler delay
            new Timer().schedule(new TimerTask() {

                @Override
                public void run() {
                   mp.release();
               }
            }, DELAY_TIME);
        }
    });

这不是最好的解决方案,但我认为这可能会对您有所帮助。

我遇到了这个问题,并解决了它,使我的MediaPlayer对象成为私有对象,因此垃圾收集器不会清理实例。希望它能帮助别人

我也遇到了同样的问题,这确实是一个垃圾收集器问题!如果将媒体播放器的实例分配给方法中的某个局部变量,则该实例在离开该方法后将不再存在,因此GC可以随时随机删除该实例

为了避免这种情况,您需要至少保留一个指向其他地方实例的指针。我创建了一个静态集来保留所有指针,它看起来如下:

private static Set<MediaPlayer> activePlayers = new HashSet<MediaPlayer>();
其中releaseOnFinishListener是一个在完成时释放媒体播放器的侦听器,就像您的一样,但也会从ActivePlayer集中删除指针:

MediaPlayer.OnCompletionListener releaseOnFinishListener = new MediaPlayer.OnCompletionListener() {
    public void onCompletion(MediaPlayer mp) {
        mp.release();
        activePlayers.remove(mp);
    }
};

我希望这能对您有所帮助。

是的,您的onClick()方法……至少我假设这就是您触发这些音效的方式?基本上就是你用来触发声音回放的任何东西。上面的代码都没有这样做。事实上,没有。这是一个游戏,所以这些声音效果是在特定事件中调用的。我可以给你看,但相信我,这不会有帮助的。显示方法调用本身不会有任何帮助,而要提供更好的图片需要显示大量代码。知道那个错误是什么吗?似乎无法通过google找到它。这对我不起作用,在调用
reset()
时抛出一个
IllegalStateException
。指向声音池示例的链接不起作用。你能更新一下吗?thanksI认为这也是问题所在,但我删除了我的release()代码,它仍然存在。我不确定这一点,但听起来停止了剪切。GC不是这样工作的。可能是相关性而不是因果关系。我在Nexus5设备上注意到了这个问题。基本上,我的应用程序流式播放音频,MediaPlayer提前了约1-5秒。其他人注意到了吗?我正在开发的应用程序也有这个问题,它让我发疯,因为我无法用现有的手机复制它,但在Galaxy S4上似乎失败了。这个bug似乎是在kitkat中引入的,只有在非常特殊的情况下才会出现。谢谢:)这确实是一个GC问题!就我而言,在全球范围内声明MediaPlayer列表就可以了。谢谢~在以后的Android Studio版本中,
Profiler
可以用来强制GC,这使得这个场景很容易测试。先生,你应该得到一枚奖章。这对我也不起作用(在Android 4.1和6.0.1上测试)
MediaPlayer player = MediaPlayer.create(context, context.getResources().getIdentifier(id, "raw", pkg));
activePlayers.add(player);
player.setOnCompletionListener(releaseOnFinishListener);
player.start();
MediaPlayer.OnCompletionListener releaseOnFinishListener = new MediaPlayer.OnCompletionListener() {
    public void onCompletion(MediaPlayer mp) {
        mp.release();
        activePlayers.remove(mp);
    }
};