android - 在使用 android videoview 时捕获所有可能的异常
问题描述
我正在使用 android videoview显示视频循环,根据我们的要求,即使其中一个视频出错,视频循环也应该继续。
为了捕获任何异常,我将相关代码包含在 try-catch 块中,如下面的代码所示。但是,在测试所有场景时,我给videoview.setVideopath()提供了错误的路径,但没有捕获到异常。我可以在 android studio 控制台中看到它报告 data source not found 错误,但 catch 块没有捕获异常。我也尝试过实现onerrorlistener
,发生这种情况时也不会调用它。
你能帮帮我吗,我附上了相关的代码和异常日志,非常感谢你的帮助。
private void DisplayVideo_VideoView(){
try {
adplayer = (ResizableVideoView) findViewById(R.id.adplayer);
String MediaStorePath = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/Videos";
// String videoPath = MediaStorePath + "/" + Root2Util.Videopathlist.get(CurrentMediaIndex).getFileName();
String videoPath = MediaStorePath + "/1" + Root2Util.Videopathlist.get(CurrentMediaIndex).getFileName();
//adplayer.setVideoPath(videopath[CurrentMediaIndex]);
adplayer.setVideoPath(videoPath);
adplayer.changeVideoSize(Root2Util.SCREEN_WIDTH, Root2Util.SCREEN_HEIGHT);
adplayer.setVisibility(View.VISIBLE);
adplayer.start();
adplayer.setKeepScreenOn(true);
adplayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
CurrentMediaIndex++;
//mp.reset();
if (CurrentMediaIndex == Root2Util.Videopathlist.size()) {
CurrentMediaIndex = 0;
}
playMedia();
// ErrorHandlerAsyncTask ErrorTask=new ErrorHandlerAsyncTask();
// ErrorTask.execute((Object)getApplicationContext(),(Object)String.valueOf(what));
return false;
}
});
} catch(Exception e) {
ErrorHandlerAsyncTask ErrorTask=new ErrorHandlerAsyncTask();
ErrorTask.execute((Object)getApplicationContext(),(Object)e.getMessage());
}
来自控制台的异常日志:
W/VideoView: Unable to open content: /storage/emulated/0/Download/Videos/1f0a9106d-d7d5-470c-
b287-3e3cad7d13fb.mp4
java.io.IOException: setDataSource failed.
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1091)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1065)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1019)
at android.widget.VideoView.openVideo(VideoView.java:352)
at android.widget.VideoView.access$2100(VideoView.java:72)
at android.widget.VideoView$7.surfaceCreated(VideoView.java:628)
at android.view.SurfaceView.updateWindow(SurfaceView.java:580)
at android.view.SurfaceView.setVisibility(SurfaceView.java:256)
at root2tech.cloudplayer.HomepageActivity.DisplayVideo_VideoView(HomepageActivity.java:728)
at root2tech.cloudplayer.HomepageActivity.playMedia(HomepageActivity.java:958)
at root2tech.cloudplayer.HomepageActivity.access$200(HomepageActivity.java:78)
at root2tech.cloudplayer.HomepageActivity$5.run(HomepageActivity.java:571)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:935)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:730)
解决方案
所以,我刚刚遇到了一个类似的问题,我需要使用 VideoView 从 URL 播放视频,而不知道 URL 是否是有效视频。我理解您为什么还要询问是否要捕获每个异常。我的 VideoView 会打印出一个 IOException 和另一个我在这个答案时不太记得的。为了解决这个问题,我使用了与您的代码非常相似的代码,但顺序不同。setOnErrorListener 为我解决了我的问题,但我将 OnErrorListener 直接放在了 VideoPlayer 初始化之后和 setVideoPath 之前。
这是有效的,因为 setVideoPath 是处理错误的地方,不幸的是,VideoView 会将这些错误打印到日志中,但它不会抛出任何使应用程序崩溃的东西(我不同意或不喜欢这一点)。因此,您的 setOnErrorListener 至少应该在设置路径之前运行,否则它不会捕获任何内容,因为错误已经被抛出(错误在开始时抛出的不够奇怪。
要将我的解决方案应用于您的代码,我会将其更改为:
private void DisplayVideo_VideoView(){
//initialize adplayer
adplayer = (ResizableVideoView) findViewById(R.id.adplayer);
//begin listening for errors
adplayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
CurrentMediaIndex++;
if (CurrentMediaIndex == Root2Util.Videopathlist.size()) {
CurrentMediaIndex = 0;
}
playMedia();
return false;
}
});
//build variables for readability
String MediaStorePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/Videos";
String videoPath = MediaStorePath + "/1" + Root2Util.Videopathlist.get(CurrentMediaIndex).getFileName();
//set path - If there is an issue with videoPath, the error should be thrown here
adplayer.setVideoPath(videoPath);
//final adplayer customizations
adplayer.changeVideoSize(Root2Util.SCREEN_WIDTH, Root2Util.SCREEN_HEIGHT);
adplayer.setVisibility(View.VISIBLE);
//begin the adplayer
adplayer.start();
adplayer.setKeepScreenOn(true);
}
推荐阅读
- php - 遍历从 PHP 序列化格式解码的地图
- crystal-reports - 字符串类型字段上的多个范围过滤器会破坏日期范围过滤器
- c# - 在excel c#中解析日期时遇到问题
- ionic-framework - IONIC 对位于自定义组件中的图像使用另一个文件目录
- javascript - 返回javascript中动态范围之间的偶数和奇数
- yii - Yii1 - 在限制和偏移之前计数,查询全部
- php - 为什么这个三元运算符不起作用?
- java - 如何忽略 SQL 更新中的列
- jenkins - 如何在 Jenkins 中使用 Artifactory 插件向 Artifactory 中的现有工件添加递归属性
- excel - 熊猫为每个 Excel 工作表创建单独的数据框