如何使用VideoView在不同布局与Activity中播放多视频及异常修复
排查修复步骤
从你描述的「互换视频文件后故障跟着第三个播放位移动、文件本身无损坏、Activity和布局是直接复制第一个页面生成」的特征,可以确定问题和视频大小、存储权限、文件完整性无关,是复制代码/布局时的引用冲突导致的,按以下优先级逐一排查:
- 优先排查布局控件ID重复问题
直接复制第一个页面的布局生成第三个页面布局时,如果你没修改VideoView控件的android:id值,会出现两个不同布局下的VideoView共用同一个资源ID的情况。安卓资源编译时的ID映射表如果出现同ID跨布局复用,页面加载时很容易出现控件引用错乱:要么拿到已经被销毁的旧页面控件触发空指针崩溃,要么直接绑定到第一个页面缓存的播放实例上,串播第一个视频。
修复:打开第三个页面对应的布局文件,给VideoView设置全局唯一的ID,比如从原来的@+id/play_video改成@+id/play_video3,同步修改对应Activity里findViewById绑定的ID,不要和其他页面的控件ID重名。 - 排查静态变量/单例导致的实例复用问题
如果你在第一个播放页的代码里,把视频路径、VideoView实例、MediaPlayer实例定义成了static修饰的静态变量,或者用全局单例持有这些播放相关对象,复制代码到第三个页面时没修改变量赋值逻辑:第三个页面启动时会直接读取静态变量里存的第一个视频的路径,导致串播;如果静态变量持有的第一个页面的VideoView实例已经随Activity销毁被回收,调用播放方法时就会触发非法内存访问崩溃。
修复:全局搜索播放逻辑相关的变量,删除所有用来持有当前页面VideoView实例、MediaPlayer实例、当前播放路径的static修饰符,每个Activity只持有自己页面的控件实例和对应视频路径,禁止跨页面共享这些播放相关的对象实例。 - 排查Intent传参/路径硬编码问题
如果你是通过Intent给播放页传递本地视频路径,复制第一个页面的启动逻辑到第三个页面入口时,很容易忘记修改putExtra里传入的路径值,甚至直接在第三个Activity的onCreate方法里硬编码写死了第一个视频的本地路径,就会出现固定加载第一个视频的问题;如果三个页面用了完全相同的Intent传参Key,取参数时也可能读到旧页面留存的缓存路径值。
修复:检查第三个页面的路径获取逻辑,不要硬编码视频路径,确认启动第三个页面时传入的是第三个视频的本地地址,三个播放页的Intent传参Key不要用重复的字符串,最好每个页面单独定义专属的传参常量。 - 补全VideoView资源释放逻辑
复制第一个页面的代码时,如果原页面没有在销毁时释放播放资源,退出第一个页面后台会留存旧的MediaPlayer播放实例缓存,打开第三个页面时VideoView会尝试绑定这个已经存在的旧实例,要么因为实例状态不匹配崩溃,要么直接继续播放旧实例加载的第一个视频流。
修复:在每个播放Activity的onDestroy生命周期中加入资源释放代码:@Override protected void onDestroy() { super.onDestroy(); if (videoView != null) { videoView.stopPlayback(); videoView = null; } }
修复完成后先卸载测试机上的旧安装包,在开发工具里执行Clean Project清除编译缓存后重新打包安装,避免旧的资源ID映射缓存导致假异常,再逐个测试三个播放页即可。
内容的提问来源于stack exchange,提问作者Sagi Lolam
相关产品推荐
相关产品推荐

