【问题标题】:android media player unresponsiveandroid媒体播放器无响应
【发布时间】:2015-03-20 08:25:24
【问题描述】:

这是我的代码,我尝试构建一个简单的应用程序,当我单击一个按钮时播放一首歌曲(单击两次将从头开始播放新歌曲)并在按下另一个按钮时停止播放。 我希望当用户将活动置于后台时,媒体播放器将“保存其状态” - 继续播放/不播放 - 当活动返回前台时,交互将保持不变。 相反,它工作正常,直到我将活动放在后台(然后它继续播放/不播放)但是当我返回它时,它似乎“创建了一个新的媒体播放器对象”,如果我在播放歌曲时单击播放,它从头开始同时播放前一首歌曲,然后单击停止 - 仅停止歌曲的新“实例”。就像我在后台活动后与媒体播放器失去联系一样。 可能是什么问题?

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();
}

但仍然是相同的行为。

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

【问题讨论】:

  • 在我看来,您正在 startPlaying() 方法中创建一个新的媒体播放器实例。
  • 那么在创建新的之前如何销毁它?

标签: java android android-mediaplayer


【解决方案1】:

您每次都在创建和销毁您的媒体播放器。尝试创建两个暂停和恢复/开始的方法。

您可以在下面找到适合我的代码。我正在开发一个在活动加载时启动主题的游戏。每次活动恢复时,媒体播放器都会在暂停位置继续播放歌曲。我重写 onDestroy() 停止, onResume 开始/恢复和 onPause() 在活动进入后台时暂停。

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();
}

希望对你有帮助。

【讨论】:

  • 我想我理解指导思想,但从技术上讲,你暂停了这首歌。现在它将从这一秒开始播放。如果我想将它循环回第一秒但保持暂停状态,以便下次单击播放按钮时它会从头开始
  • 对不起,但它仍然代表相同的行为
  • 我已经用对我有用的代码修改了最初的答案。
  • 我编辑了这个问题,你知道注释部分吗?
  • 如果您不释放媒体播放器,它必须保持活动状态。我已经测试了我的代码,如果我在 inPause 方法中什么都不做,那么当活动处于后台时,播放器会继续保持相同的状态。我建议你试试我的代码,然后调整它。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多