本文共 4732 字,大约阅读时间需要 15 分钟。
如下是最近在搞webview播放视频,全屏切换需求的总结,供同仁参考,避免踩坑,提高工作效率,早点下班,丰富个人生活!
能不用webview播放视频就不要用了,自己封装系统的播放器组件都比使用webview好,webview播放视频的兼容性问题太多
应用前后台切换时,相应Activity生命周期方法中要调用webview的onResume与onPause的方法,否则应从前台切换到后台后视频还是在播放的,还有声音的。
有些低端的手机(5.0以下)可能有兼容性问题,开启硬件加速后可能会出现崩溃,这种情况特殊规避一下,不开启硬件加速
loadUrl与PostUrl的最关键区分是webview加载目标url发起的http请求是get的方式还是post方式请求,顾名思义PostUrl产生的是post请求。
某些网站的web服务器对于某个url的请求是配置为get方式的,如果换post方式该服务器会返回405或4.04的页面 如下截图是使用postUrl请求一个普通页面,服务器返回not found的结果页创建webview的时候需要传context的实例,如果是“插件”组件化的架构,可能会存在当前应用的Applicaton context与当前模块的context,
所以实例化webview时需要传当前应用的context,一般传application的实例即可,否则android7.0以上的手机会遇到如下崩溃问题W/System.err: android.content.res.Resources$NotFoundException: String resource ID #0x2060006 at android.content.res.Resources.getText(Resources.java:380) at android.content.res.Resources.getString(Resources.java:474) at android.content.Context.getString(Context.java:562) at org.chromium.content.browser.ContentVideoView.(ContentVideoView.java:11) at org.chromium.content.browser.ContentVideoView.createContentVideoView(ContentVideoView.java:79) at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method) at org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:9) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:183) at android.app.ActivityThread.main(ActivityThread.java:7014) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:514)
使用webview的视频全屏播放功能,WebChromeClient的回调方法之一getDefaultVideoPoster需要Override一下,如下为示例代码
否则Android8.0以上的手机可以会遇到如下崩溃java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object referenceat com.android.webview.chromium.WebViewContentsClientAdapter.getDefaultVideoPoster(WebViewContentsClientAdapter.java:552)at org.chromium.android_webview.DefaultVideoPosterRequestHandler$1.run(DefaultVideoPosterRequestHandler.java:2)at android.os.Handler.handleCallback(Handler.java:751)at android.os.Handler.dispatchMessage(Handler.java:95)at android.os.Looper.loop(Looper.java:154)at android.app.ActivityThread.main(ActivityThread.java:6776)at java.lang.reflect.Method.invoke(Native Method)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
如下示例代码为getDefaultVideoPoster方法的Override示例
class WebChromClientImp extends WebChromeClient{ @Override public Bitmap getDefaultVideoPoster() { try{ //这个地方是加载h5的视频列表 默认图 点击前的视频图 return BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.icon_default); }catch(Exception e){ return super.getDefaultVideoPoster(); } }}
使用默认的全屏方案(WebChromeClient的onShowCustomView回调)有很多兼容性问题,特别是Android5.0以下的ROM,建议直接在H5页面针对低于包括5.0的rom,隐藏视频全屏按钮。
估据是系统播放器,webview的兼容器问题,关闭webview实例的缓存,如下为示例代码
if ("Meizu".equals(android.os.Build.BRAND) && "MX4 Pro".equals(android.os.Build.MODEL) && "5.1.1".equals(android.os.Build.VERSION.RELEASE)) { webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); }
当你的APP targetVersion >= 21时,如果不显式让webview开启加载混合内容的开关,会影响到图片和视频、js、cs等资源的加载,影响到界面的显示,视频的播放。
注:如果你的targetVersion<21时,可以忽略这个操作。原因是webview对于targetVersion>=21时,默认不加载混合内容。反之,默认是允许的 如下为示例代码/** public static final int MIXED_CONTENT_ALWAYS_ALLOW = 0; public static final int MIXED_CONTENT_COMPATIBILITY_MODE = 2; public static final int MIXED_CONTENT_NEVER_ALLOW = 1;*/if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);}//需要升级complieversion为21以上,不升级的话,用反射的方式来实现,如下代码所示try { Method m = WebSettings.class.getMethod("setMixedContentMode", int.class); if ( m == null ) { Log.e("WebSettings", "Error getting setMixedContentMode method"); } else { m.invoke(webView.getSettings(), 2); // 2 = MIXED_CONTENT_COMPATIBILITY_MODE Log.i("WebSettings", "Successfully set MIXED_CONTENT_COMPATIBILITY_MODE"); }}catch (Exception ex) { Log.e("WebSettings", "Error calling setMixedContentMode: " + ex.getMessage(), ex);}
混合内容在以下情况下出现:初始 HTML 内容通过安全的 HTTPS 连接加载,但其他资源(例如,图像、视频、样式表、脚本)则通过不安全的
HTTP 连接加载。之所以称为混合内容,是因为同时加载了 HTTP 和 HTTPS 内容以显示同一个页面,且通过 HTTPS 加载的初始请求是安全的。现代浏览器会针对此类型的内容显示警告,以向用户表明此页面包含不安全的资源。