用布尔标志控制MediaPlayer行为



我的应用使用MediaPlayer对象播放背景音乐。我将它与其他全局变量一起存储在.java文件中——还有什么?-全局变量,所以访问它和其他变量,我使用这个调用:

GlobalVariables.mPlayer

我想让MediaPlayer在我的应用程序中切换活动时继续播放音频,但在应用程序失去焦点时暂停。为了实现这一目标,我声明了一个布尔值,叫做keepPlaying,也存储在GlobalVariables中,这样它就可以被应用程序中的所有活动访问。这个想法是让活动检查布尔标志每次onStop()被调用,如果它发现keepPlaying = false,暂停播放,否则什么都不做(保持播放)。我在每次调用startActivity()之前将标志设置为true,并在每次调用onResume()时将其设置为false。

如果我正确理解活动生命周期,当切换活动时,我的应用程序将首先调用当前的OnStop()。首先我将keepPlaying设为true,然后调用onStop()。该方法包括三行:

super.onStop();
if(GlobalVariables.keepPlaying == false)
    GlobalVariables.mPlayer.pause();

所以它应该保持播放进行每当我做startActivity调用,但暂停播放当我最小化应用程序。然后,在下一个活动的onResume()方法,我设置标志为false:

if(GlobalVariables.keepPlaying == true){
    GlobalVariables.keepPlaying = false;
}else{
    GlobalVariables.mPlayer.start();

然而,应用程序没有按照我想要的方式运行。切换活动时仍然会暂停音频播放。我已经尝试创建getter和setter方法的keepPlaying标志,但还没有修复它,所以我知道这不是一个访问问题。

谁能想到这个方法不起作用的任何原因或者我如何修复它?

谢谢!

[EDIT]根据要求,这里是一个更完整的代码示例。我现在不能用自己的电脑,但这应该是一个精确的重现。假定所有必要的导入。

public class GlobalVariables{
    public boolean keepPlaying;
    public MediaPlayer mPlayer;
    // Getter and setter methods, found to be unnecessary
    public void setKeepPlaying(boolean input){keepPlaying = input;}
    public boolean getKeepPlaying(){return keepPlaying;}
}
// First activity. Music plays after starting Activity, as expected.
public class FirstActivity extends Activity{
    @Override
    public void onCreate(...){
        super.onCreate(...);
        GlobalVariables.keepPlaying = false;
        GlobalVariables.mPlayer.create(this, R.raw.music);
    }
    @Override
    public void onStop(){
        super.onStop();
        // Check to see if we want to stop audio playback
        if(GlobalVariables.keepPlaying == false){
            GlobalVariables.mPlayer.pause();
    }
    @Override
    public void onResume(){
        super.onResume();
        // If audio is already playing, set keepPlaying to false. Otherwise, start audio playback.
        if(GlobalVariables.keepPlaying == true) //Thus audio is playing
            GlobalVariables.keepPlaying = false;
        else
            GlobalVariables.mPlayer.start();
    }
    public void launchNextActivity(){
        GlobalVariables.keepPlaying = true;
        startActivity(new Intent(FirstActivity.this, SecondActivity.class));
    }

}

Code for SecondActivity is the same as FirstActivity. When starting SecondActivity, the music abruptly stops. When hiding the app and resuming it, the music begins playing again.

我想出了一个不涉及服务的解决方案——对于一个简单的小应用程序来说,这是完美的。

您需要创建一个公共int变量来跟踪有多少活动想要为MediaPlayer播放音乐,这是通过将它放在一个名为GlobalVariables的.java文件中实现的:

public int activitiesPlaying;

确保将这个int初始化为0。在我的例子中,我在主菜单活动中完成了这一步,在它的onStart()方法中,这样返回到主菜单就会停止音乐。

GlobalVariables.activitiesPlaying = 0;

从那时起,所有需要操作的是每个Activity的onStart()和onStop()方法,你想要播放音乐。在我的例子中,音乐应该在Activity启动时播放,所以onStart()非常简单:

public void onStart(){
    super.onStart();
    GlobalVariables.activitiesPlaying++;
    GlobalVariables.mPlayer.start(); // MediaPlayer is stored in GlobalVariables
}

onStop()是类似的,但需要检查actitiesplaying的值。首先,由于Activity正在停止,我们减少activitesPlaying。如果是<= 0,则暂停音乐播放,为了便于管理,将actitiesplaying设置回0,以防由于某种原因将其设置为负值。这可能没有必要,但是及时一针。

public void onStop(){
    super.onStop();
    GlobalVariables.activitiesPlaying--;
    if(GlobalVariables.activitiesPlaying <= 0){
        GlobalVariables.activitiesPlaying = 0;
        GlobalVariables.mPlayer.pause();
    }
}

由于活动生命周期的顺序,不可能像我上面尝试的那样使用布尔值,因为当下一个活动开始时,它将被设置为true,但在检查MediaPlayer是否应该继续播放之前,它将被设置为false。然而,使用整数值使这个决策更加灵活,因为只要它大于0,音乐就会继续播放。

我意识到有可能使用服务来实现类似的结果,我鼓励每个研究这个问题的人都考虑一下。但是考虑到我的编程背景和对自定义服务的不熟悉,这个解决方案对我来说是最有意义的。

最新更新