android 媒体播放器无响应

android media player unresponsive

这是我的代码,我尝试构建简单的应用程序,每当我单击一个按钮时播放一首歌曲(单击两次将从头开始播放一首新歌曲)并在按下另一个按钮时停止播放。 我希望当用户将 activity 置于后台时,媒体播放器将 "save its state" - 继续 playing/not 播放 - 当 activity return 到前景交互将保持不变。 相反,它工作正常,直到我将 activity 放在后台(然后它保持 playing/not 播放)但是当我 return 它回来时它看起来像 "a new media player object was created" 如果我点击播放播放歌曲时,它会与上一首同时从头开始播放歌曲,然后单击停止 - 仅停止歌曲的新 "instance"。就像 activity 在后台后我与媒体播放器失去连接一样。 可能是什么问题?

public class MainActivity extends ActionBarActivity {
    private MediaPlayer mediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button buttonStart = new Button(this);
    Button buttonStop = new Button(this);

    buttonStart.setText(R.string.button_start_text);
    buttonStop.setText(R.string.button_stop_text);


    buttonStart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startPlaying();
        }
    });

    buttonStop.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            stopPlaying();
        }
    });

    ViewGroup layout = (ViewGroup) findViewById(R.id.mainLayout);
    layout.addView(buttonStart);
    layout.addView(buttonStop);
}

void startPlaying(){
    stopPlaying();
    mediaPlayer = MediaPlayer.create(this,R.raw.dreams);
    mediaPlayer.start();
}

void stopPlaying(){
    if (mediaPlayer != null){
        try {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
                mediaPlayer.reset();
                mediaPlayer.release();
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}

我也更改了代码,像这样(现在有 3 个按钮:播放、停止、暂停:

void startPlaying(){
    if (mediaPlayer == null) {
        mediaPlayer = MediaPlayer.create(this, R.raw.dreams);
    }
    mediaPlayer.start();
}

void stopPlaying(){
    if (mediaPlayer != null){
        try {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
                mediaPlayer.prepare();
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}

void pausePlaying(){
    if (mediaPlayer != null) mediaPlayer.pause();
}

但仍然是相同的行为。

我的一些见解: 在用户将 activity 置于后台之前,成员 mediaPlayer 是一些构造的 android 对象。 当 activity return 到前景 mediaPlayer 为空时。 为什么是这样? 也许我误解了 activity 的想法,但我认为它在其生命周期中保持其成员的价值观。

你每次都在创建和销毁你的媒体播放器。尝试为 pause 和 resume/start 创建两个方法。

您可以在下面找到适合我的代码。我正在开发一款在 activity 加载时启动主旋律的游戏。每次 activity 恢复时,媒体播放器都会继续播放暂停位置的歌曲。我覆盖 onDestroy() 停止,onResume 到 start/resume 和 onPause() 在 activity 进入背景时暂停。

public MediaPlayer mp=null;

@Override
protected void onDestroy() {
    if (mp!=null)
        mp.stop();

    super.onStop();
}

@Override
protected void onResume() {

    super.onResume();

    if (mp==null){
        self=this;
        Thread thMusic= new Thread(new Runnable(){
            public void run(){
                mp= MediaPlayer.create(self,R.raw.dizzy );
                mp.start();
            }
        });

        thMusic.start();
    }
    else
        mp.start();
}

@Override
protected void onPause() {
    if (mp!=null)
        mp.pause();

    super.onPause();
}

希望对您有所帮助。

http://developer.android.com/guide/components/activities.html 保存 activity 状态提供了可以解释发生了什么的详细信息。 简而言之,当 activity 在后台时,当用户将其导航回前台时,它可能会被 OS 杀死并再次创建。 onSaveInstanceState() 应该实施,除非只恢复 UI 个对象 但不是 class 个成员