You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Media Player报错“Unable to create media player”:VideoView复用问题求助

解决Android VideoView/MediaPlayer复用导致的播放失败问题

看起来你遇到的是典型的VideoView内部MediaPlayer资源未正确释放导致的播放异常问题。第一次播放视频后,MediaPlayer处于占用状态,当你从字幕Activity返回或跳转到最后一个Activity时,旧的MediaPlayer资源没有被清理,导致新的播放请求无法创建或初始化媒体播放器。

我帮你梳理几个关键修复点,直接对应你的代码问题:

核心修复步骤

  • 在重新设置视频源前,强制重置/释放VideoView的MediaPlayer:避免旧的播放器资源占用导致冲突
  • 优化onActivityResult中的逻辑:移除不必要的重复Handler延迟,确保视频初始化代码执行顺序正确
  • 统一管理VideoView的状态:在Activity生命周期的关键节点(比如onPause、onResume)也做相应的状态保存和恢复

修改后的主Activity代码

public class TelaHome extends Activity { 
    VideoView video; 
    int num = 0; 
    ImageView videocheck; 
    ImageView legcheck; 
    Button butvideo; 
    Button butleg; 
    Button butstart; 
    TextView textovideo; 
    String nomedovideo; 
    String urivideo; 
    Uri Uridovideo; 
    int cont = 0; 
    int stop = 0; 
    Boolean simvid = false; 
    Boolean simleg = false; 
    Intent videointent; 
    Intent letraintent; 
    Bundle pacotemain; 
    Bundle letra; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.tela_home); 

        butstart = findViewById(R.id.butstart);
        butvideo = findViewById(R.id.butvideo);
        butleg = findViewById(R.id.butleg);
        videocheck = findViewById(R.id.imgvideocheck);
        legcheck = findViewById(R.id.imglegcheck);
        textovideo = findViewById(R.id.textovideo);
        video = findViewById(R.id.videoView);

        textovideo.setMovementMethod(new ScrollingMovementMethod());
        butstart.setVisibility(View.INVISIBLE);
        videocheck.setImageResource(R.mipmap.ic_not_checked);
        textovideo.setText("");

        MediaController mc = new MediaController(this);
        mc.setAnchorView(video);
        video.setMediaController(mc);

        butvideo.setOnClickListener(view -> launchMainActivity());
    }

    // 新增:在Activity暂停时释放VideoView资源
    @Override
    protected void onPause() {
        super.onPause();
        if (video != null && video.isPlaying()) {
            video.pause();
        }
    }

    // 新增:在Activity销毁时彻底释放MediaPlayer
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (video != null) {
            video.stopPlayback(); // 这会内部释放MediaPlayer资源
        }
    }

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
        super.onActivityResult(requestCode, resultCode, data); // 不要忘记调用父类方法!

        if (requestCode == 1) { 
            if(resultCode == Activity.RESULT_OK){ 
                videointent = data; 
                pacotemain = videointent.getExtras(); 
                if (pacotemain != null) { 
                    nomedovideo = pacotemain.getString("arquivo"); 
                    urivideo = pacotemain.getString("curPF"); 
                    if (urivideo != null) { 
                        // 关键修复:先停止当前播放并重置VideoView
                        if (video.isPlaying()) {
                            video.stopPlayback();
                        }
                        // 重新设置视频源
                        Uridovideo = Uri.parse(urivideo); 
                        video.setVideoURI(Uridovideo); 
                        video.setOnPreparedListener(mediaPlayer -> video.start()); 
                    } 

                    if (nomedovideo != null) {
                        // 简化格式获取逻辑,避免数组操作的潜在问题
                        String formato = nomedovideo.substring(nomedovideo.length() - 3);
                        textovideo.setText(nomedovideo);
                    }
                } 

                new Handler(Looper.getMainLooper()).postDelayed(() -> { 
                    if (video.isPlaying()) { 
                        cont++; 
                        videocheck.setImageResource(R.mipmap.ic_checked); 
                        simvid = true; 
                    } 
                }, 1000); 
            } 
        } 

        if (requestCode == 7) { 
            if(resultCode == Activity.RESULT_OK){ 
                letraintent = data; 
                letra = letraintent.getExtras(); 
                if (letra != null){ 
                    legcheck.setImageResource(R.mipmap.ic_checked); 
                    simleg = true; 
                } 
            } 
        } 

        new Handler(Looper.getMainLooper()).postDelayed(() -> 
            abrirplay(simvid, simleg, pacotemain, letra), 
        1500); 
    }

    // 补充launchMainActivity方法(你的代码里没贴,这里假设是打开图库的逻辑)
    private void launchMainActivity() {
        // 这里写打开图库选择视频的Intent逻辑
    }

    private void abrirplay(Boolean simvid, Boolean simleg, Bundle pacotemain, Bundle letra) {
        // 你的跳转逻辑
    }
}

关键修改说明

  1. 添加生命周期方法管理:在onPause中暂停播放,onDestroy中调用stopPlayback()彻底释放MediaPlayer资源,这是避免资源泄漏的核心。
  2. 重置VideoView再设置新视频:在requestCode=1的分支里,每次设置新的视频URI前,先停止当前播放并释放旧的MediaPlayer,避免资源冲突。
  3. 修复Handler的使用:使用Looper.getMainLooper()确保Handler在主线程运行,避免潜在的线程问题。
  4. 简化格式获取逻辑:用substring替代数组操作,减少代码复杂度和潜在错误。
  5. 调用父类的onActivityResult:你之前的代码漏掉了super.onActivityResult(...),这可能导致ActivityResult的逻辑异常。

另外,关于最后一个Activity的VideoView问题,同样要遵循这个原则:每次设置视频前,先调用stopPlayback()释放旧的MediaPlayer资源,再设置新的URI,这样就能避免"Unable to create media player"的错误。

内容的提问来源于stack exchange,提问作者Reinaldo Neto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:28:12