Android Studio开发点击返回键无法停止MediaPlayer播放问题求助
问题根因
- 第一,
onBackPressed方法的逻辑缩进错误,super.onBackPressed()和finish()只有在MediaPlayer处于播放状态时才会执行,若触发返回时刚好音频播放完成、还未到下一轮创建MediaPlayer的时间点,就会出现无法返回的问题。 - 第二,Handler的循环延时任务没有被取消,即便Activity销毁,已经入队的Runnable还是会到点执行,不仅会重新创建MediaPlayer继续播放音频,还会操作已经被销毁的Activity2的控件,导致无图片显示、内存泄漏等问题。
- 第三,每次执行Runnable时都重新创建MediaPlayer,旧的MediaPlayer实例没有提前释放,会出现多段音频重叠播放的情况。
修复方案
第一步:把Handler和Runnable改成Activity的全局成员变量
不要在onCreate里定义成局部变量,否则onBackPressed里没法调用取消任务的方法。
第二步:修正onBackPressed的逻辑,退出时先取消循环任务,再释放资源
第三步:每次创建新的MediaPlayer之前,先释放旧的实例
修复后代码示例
public class Activity2 extends AppCompatActivity { public MediaPlayer mp = new MediaPlayer(); Button button; ImageView im; Context context; int current_img = 0; int current_aud = 0; boolean flag= false; int[] sounds={R.raw.anar,R.raw.ab,R.raw.abi}; int[] images = { R.drawable.anar, R.drawable.water , R.drawable.abi}; String[] texts={"انار","آب","آبی"}; AnimationDrawable animation = new AnimationDrawable(); // 把Handler和Runnable改成全局成员 private Handler handler = new Handler(); private Runnable runnable; @Override public void onBackPressed() { // 先取消循环任务,避免后续继续执行 if (handler != null && runnable != null) { handler.removeCallbacks(runnable); } // 释放MediaPlayer资源,不管当前是否在播放都要处理 if (mp != null) { if (mp.isPlaying()) { mp.stop(); } mp.release(); mp = null; } // 这两行要放到if外面,不管什么情况都要执行返回 super.onBackPressed(); finish(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final TextView textView=findViewById(R.id.textView); im = findViewById(R.id.imageView); im.setImageResource(R.drawable.anar); runnable = new Runnable() { int i = 0; int j = 0; public void run() { textView.setText(texts[i]); im.setImageResource(images[i]); i++; // 先释放旧的MediaPlayer再创建新的 if (mp != null) { if (mp.isPlaying()) { mp.stop(); } mp.release(); } mp = MediaPlayer.create(Activity2.this, sounds[j]); mp.start(); j++; if (j > sounds.length - 1) { j = 0; } if (i > images.length - 1) { i = 0; } handler.postDelayed(this, 5000); } }; // 启动第一次任务 handler.post(runnable); } }
额外注意事项
- 建议两个Activity使用独立的布局文件,避免共用
activity_main导致控件内容被互相覆盖,如果返回Activity1后无图片显示,检查Activity1的onResume生命周期里是否有给对应ImageView设置图片资源。
内容的提问来源于stack exchange,提问作者mojtaba
相关产品推荐
相关产品推荐

