使用WebView的注意事项(加载视频播放页)

如下是最近在搞webview播放视频,全屏切换需求的总结,供同仁参考,避免踩坑,提高工作效率,早点下班,丰富个人生活!

方案选型建议

能不用webview播放视频就不要用了,自己封装系统的播放器组件都比使用webview好,webview播放视频的兼容性问题太多

webview生命周期方法

应用前后台切换时,相应Activity生命周期方法中要调用webview的onResume与onResume的方法,否则应从前台切换到后台后视频还是在播放的,还有声音的。

开启Weview的硬件加速

有些低端的手机(5.0以下)可能有兼容性问题,开启硬件加速后可能会出现崩溃,这种情况特殊规避一下,不开启硬件加速

loadUrl与postUrl的区别

loadUrl与PostUrl的最关键区分是webview加载目标url发起的http请求是get的方式还是post方式请求,顾名思义PostUrl产生的是post请求。
某些网站的web服务器对于某个url的请求是配置为get方式的,如果换post方式该服务器会返回405或4.04的页面
如下截图是使用postUrl请求一个普通页面,服务器返回not found的结果页
这里写图片描述

创建webview时转入的context

创建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.<init>(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)

WebChromeClient的getDefaultVideoPoster

使用webview的视频全屏播放功能,WebChromeClient的回调方法之一getDefaultVideoPoster需要Override一下,如下为示例代码
否则Android8.0以上的手机可以会遇到如下崩溃

java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
at 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();
        }
    }
}

webview播放视频全屏的兼容性

使用默认的全屏方案(WebChromeClient的onShowCustomView回调)有很多兼容性问题,特别是Android5.0以下的ROM,建议直接在H5页面针对低于包括5.0的rom,隐藏视频全屏按钮。

Meizu MX4 pro多次播放后有声无图

估据是系统播放器,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);
        }

允许webview加载Mixed Content(混合内容)

当你的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
加载的初始请求是安全的。现代浏览器会针对此类型的内容显示警告,以向用户表明此页面包含不安全的资源。

猜你喜欢

转载自blog.csdn.net/SCHOLAR_II/article/details/81330403