如何在带PagerAdapter的Fragment页面中点击返回键时正确停止MediaPlayer?
解决PagerAdapter中Fragment返回时MediaPlayer无法停止的问题
问题根源
你的MediaPlayer是在onCreateView()方法里定义的局部变量,当用户点击返回键,Fragment被销毁时,这个局部变量的引用会直接丢失,导致你无法调用它的stop()和release()方法,音频自然会持续播放下去。
正确的解决方案
我们需要调整MediaPlayer的作用域,并利用Fragment的生命周期方法,在合适的时机停止并释放资源:
- 将
MediaPlayer声明为Fragment的成员变量,而非局部变量,这样在生命周期方法里能访问到它 - 在Fragment的
onStop()或onDestroyView()方法中,执行停止播放+释放资源的操作(推荐用onStop(),因为Fragment不可见时就该停止音频,更符合用户预期) - 增加空值判断,避免出现空指针或非法状态异常
修改后的完整代码
package com.androidbasedcollectionofstories; import android.graphics.drawable.AnimationDrawable; import android.media.MediaPlayer; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; public class BRUSH1 extends Fragment { // 把MediaPlayer改为Fragment成员变量,扩大作用域 private MediaPlayer sound; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.brushing1, container, false); ImageView imageview = (ImageView) view.findViewById(R.id.imageView1); if(imageview == null) throw new AssertionError(); imageview.setBackgroundResource(R.drawable.animbrushing1); AnimationDrawable anim = (AnimationDrawable) imageview.getBackground(); anim.start(); // 初始化MediaPlayer并开始播放 sound = MediaPlayer.create(getActivity(), R.raw.brushingtitle); sound.start(); return view; } @Override public void onStop() { super.onStop(); // 停止播放并释放资源,同时做空值判断 if (sound != null) { if (sound.isPlaying()) { sound.stop(); } sound.release(); sound = null; // 置空避免内存泄漏 } } }
额外说明
- 一定要调用
release():MediaPlayer属于系统硬件资源,不主动释放会造成资源泄漏,甚至影响其他应用的音频播放 - 如果需要在Fragment重新可见时恢复播放,可以在
onStart()方法中重新初始化MediaPlayer并调用start() - 如果你是用ViewPager+Fragment的组合,还要注意Fragment的预加载特性,可能需要在Fragment切换时也处理音频的启停逻辑
内容的提问来源于stack exchange,提问作者Emey
相关产品推荐
相关产品推荐

