这是我的代码,我尝试构建一个简单的应用程序,每当我点击一个按钮时播放一首歌(点击两次将从头开始播放新歌)&按下另一个按钮时停止播放。 我希望当用户将活动放在后台时,媒体播放器将“保存其状态” - 继续播放/不播放 - 当活动返回到前台时,交互将保持不变。 相反,它工作正常,直到我把活动放在后台(然后它继续播放/不播放)但当我返回它时,它似乎“创建了一个新的媒体播放器对象”,如果我在播放歌曲时单击播放,它开始与前一首歌同时播放歌曲,然后单击停止 - 仅停止歌曲的新“实例”。就像我在活动处于后台后与媒体播放器的松散连接一样。 可能是什么问题?
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对象。
当活动返回到foregound mediaPlayer
时为null。
为什么是这样?
也许我错了活动的想法,但我认为它在其生命周期中保持其成员的价值。
答案 0 :(得分: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();
}
我希望这会对你有所帮助。
答案 1 :(得分:0)
http://developer.android.com/guide/components/activities.html
保存活动状态提供了可以解释发生的事情的详细信息。
简而言之,当活动在后台时,当用户将其导航回前景时,操作系统可能会再次杀死并创建活动。
除非仅恢复UI对象,否则应实现onSaveInstanceState()
但不是班级成员