android开发分享Android WebView基础应用详解

目录一、webview的基础配置二、webview支持播放音乐三、webview支持视频播放四、webchromeclient五、webviewclient1、重定向问题2、实现预加载3、增加错误页面

目录
  • 一、webview的基础配置
  • 二、webview支持播放音乐
  • 三、webview支持视频播放
  • 四、webchromeclient
  • 五、webviewclient
    • 1、重定向问题
    • 2、实现预加载
    • 3、增加错误页面展示限制
    • 4、解决页面白屏问题

附github源码:webviewexplore

上述就是android开发分享Android WebView基础应用详解的全部内容,如果对大家有所用处且需要了解更多关于Android学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

一、webview的基础配置

  websettings ws = getsettings();  ws.setbuiltinzoomcontrols(true);// 隐藏缩放按钮  ws.setlayoutalgorithm(websettings.layoutalgorithm.normal);// 排版适应屏幕     ws.setusewideviewport(true);// 可任意比例缩放  ws.setloadwithoverviewmode(true);// setusewideviewport方法设置webview推荐使用的窗口。setloadwithoverviewmode方法是设置webview加载的页面的模式。     ws.setsaveformdata(true);// 保存表单数据  ws.setjavascriptenabled(true); // 是否能与js交互【如果业务中无js交互,建议将此项关闭】  ws.setgeolocationenabled(true);// 启用地理定位【如果业务中无此业务,建议将此项关闭】  ws.setdomstorageenabled(true);  ws.setjavascriptcanopenwindowsautomatically(true);//允许js alert对话框等打开【如果业务中无此业务,建议将此项关闭】  ws.setsupportmultiplewindows(true);// 新加

二、webview支持播放音乐

  //是否支持播放音乐  ws.setpluginstate(websettings.pluginstate.on);  ws.setmixedcontentmode(websettings.mixed_content_always_allow);     //是否需要用户点击才播放  ws.setmediaplaybackrequiresusergesture(true);

三、webview支持视频播放

android webview播放视频(包括全屏播放)

四、webchromeclient

  /**   * webchromeclient是辅助webview处理javascript的对话框,网站图标,网站title,加载进度等  */  setwebchromeclient(new xwebchromeclient());

其具体覆盖方法如下: 

      public static class xwebchromeclient extends webchromeclient {             /**           * 获取网页加载进度           * @param view           * @param newprogress           */          @override          public void onprogresschanged(webview view, int newprogress) {              super.onprogresschanged(view, newprogress);              log.d(tag, "onprogresschanged---> newprogress:" + newprogress);          }             /**           * 获取网站标题 (android 6.0 以下通过title获取【捕捉http error】)           *           * @param view           * @param title           */          @override          public void onreceivedtitle(webview view, string title) {              super.onreceivedtitle(view, title);              log.d(tag, "onreceivedtitle---> title:" + title);              if (webtitlecallback != null) {                  webtitlecallback.onreceived(title);              }              if (build.version.sdk_int < build.version_codes.m) {                  if (title.contains("404") || title.contains("500") || title.contains("error")) {                      view.loadurl("about:blank"); // 避免出现默认的错误界面                      // 在这里可以考虑显示自定义错误页                      // showerrorpage();                  }              }          }             /**           * 网站图标           *           * @param view           * @param icon           */          @override          public void onreceivedicon(webview view, bitmap icon) {              super.onreceivedicon(view, icon);              log.d(tag, "icon:" + icon);          }             /**           * 拦截alert弹框           *           * @param view           * @param url           * @param message           * @param result           * @return           */          @override          public boolean onjsalert(webview view, string url, string message, jsresult result) {              log.d(tag, "onjsalert");              return super.onjsalert(view, url, message, result);          }             /**           * 拦截 confirm弹框           *           * @param view           * @param url           * @param message           * @param result           * @return           */          @override          public boolean onjsconfirm(webview view, string url, string message, jsresult result) {              log.d(tag, "onjsconfirm");              return super.onjsconfirm(view, url, message, result);          }             /**           * 打印console信息           *           * @param consolemessage           * @return           */          @override          public boolean onconsolemessage(consolemessage consolemessage) {              log.d(tag, "onconsolemessage");              return super.onconsolemessage(consolemessage);          }             /**           * 该方法在web页面请求某个尚未被允许或拒绝的权限时回调           *           * @param request           */          @override          public void onpermissionrequest(permissionrequest request) {              super.onpermissionrequest(request);              log.d(tag, "onpermissionrequest---> request:" + request);          }      }

五、webviewclient

  /**   * webviewclient就是帮助webview处理各种通知、请求事件的   */  setwebviewclient(new xwebviewclient());

其具体覆盖方法如下: 

      public class xwebviewclient extends webviewclient {             @override          public void onpagestarted(webview view, string url, bitmap favicon) {              super.onpagestarted(view, url, favicon);              log.d(tag, "onpagestarted---> url:" + url);          }             @override          public void onpagefinished(webview view, string url) {              super.onpagefinished(view, url);              log.d(tag, "onpagefinished---> url:" + url);          }             /**           * web页面加载错误时回调,这些错误通常都是由无法与服务器正常连接引起的。           *           * @param view           * @param errorcode           * @param description           * @param failingurl           */          //android6.0之前的方法 【在新版本中也可能被调用,所以加上一个判断,防止重复显示】          @override          public void onreceivederror(webview view, int errorcode, string description, string failingurl) {              super.onreceivederror(view, errorcode, description, failingurl);              if (build.version.sdk_int < build.version_codes.m) {                  // 断网或者网络连接超时                  showreceivederrorpage(view, errorcode, description, failingurl);              }          }             /**           * 当服务器返回错误码时回调           *           * @param view           * @param request           * @param errorresponse           */          //6.0新增方法          @requiresapi(api = build.version_codes.m)          @override          public void onreceivedhttperror(webview view, webresourcerequest request, webresourceresponse errorresponse) {              super.onreceivedhttperror(view, request, errorresponse);              // 这个方法在6.0才出现              if (build.version.sdk_int >= build.version_codes.m) {                  int statuscode = 0;                  if (errorresponse != null) {                      statuscode = errorresponse.getstatuscode();                  }                  log.d(tag, "onreceivedhttperror---> code = " + statuscode);                  if (404 == statuscode || 500 == statuscode) {                      view.loadurl("about:blank");// 避免出现默认的错误界面                      // 在这里可以考虑显示自定义错误页                      // showerrorpage();                  }              }          }      }

还有如下方法,在使用时尤其要注意:

1、重定向问题

在 shouldoverrideurlloading 方法可进行重定向的判断跟处理:

          /**           * 重定向分析:           *           * @param view           * @param request           * @return true: 表示当前url已经加载完成,即使url还会重定向都不会再进行加载           * false: 表示此url默认由系统处理,该重定向还是重定向,直到加载完成           */          //android7.0之后的方法          @requiresapi(api = build.version_codes.n)          @override          public boolean shouldoverrideurlloading(webview view, webresourcerequest request) {              log.d(tag, "shouldoverrideurlloading new---> url:" + request.geturl());                 analysisrequest(request);                 string url = (request.geturl()).tostring();              boolean hasgesture = request.hasgesture();              boolean isredirect = request.isredirect();                 return shouldoverride(view, url);          }

其webview重定向需要考虑的case如下:

1、是最普通的http url【不含.doc .apk等下载url】

2、下载的http url【如.doc .apk等】

3、非http或https自定义url 【如 “weixin:// alipays://等】

【deprecated】如果期望打开web页时不自动唤起app,可通过 request.hasgesture()【是否】点击来判断,如果是true才唤起第三方app。(此种方案有时不太准确,故可采用下面方案)

【recommend】定义一个boolean值如:isclickweb = false,在ontouchevent down方法中,将其赋值为true。在必要位置添加判断即可【具体可参考代码】

          /**           * 自定义重定向处理方法           * @param view           * @param url           * @return           */          private boolean shouldoverride(webview view, final string url) {              //业务需要可做处理              redirectionjudge(view, url);                 if (schemeutil.ishttpprotocol(url) && !schemeutil.isdownloadfile(url)) {                  return false;              }                 if (schemeutil.ishttpprotocol(url) && schemeutil.isdownloadfile(url)) {                  if (isclickweb) {                      opendialog(url);                      return true;                  }              }                 if (!schemeutil.ishttpprotocol(url)) {                  boolean isvalid = schemeutil.isschemevalid(context, url);                  if (isvalid && isclickweb) {                      opendialog(url);                  } else {                      log.d(tag, "此scheme无效[比如手机中未安装该app]");                  }                  return true;              }              return false;          }

2、实现预加载

在 shouldinterceptrequest 方法中可实现资源预加载:

          /**           * 【实现预加载】           * 有时候一个页面资源比较多,图片,css,js比较多,还引用了jquery这种庞然巨兽,           * 从加载到页面渲染完成需要比较长的时间,有一个解决方案是将这些资源打包进apk里面,           * 然后当页面加载这些资源的时候让它从本地获取,这样可以提升加载速度也能减少服务器压力。           */          @nullable          @override          public webresourceresponse shouldinterceptrequest(webview view, webresourcerequest request) {              if (request == null) {                  return null;              }              string url = request.geturl().tostring();              log.d(tag, "shouldinterceptrequest---> " + url);              return getwebresourceresponse(url);          }

          protected webresourceresponse getwebresourceresponse(string url) {              //此处[tag]等需要跟服务端协商好,再处理              if (url.contains("[tag]")) {                  try {                      string localpath = url.replacefirst("^http.*[tag]\]", "");                      inputstream is = getcontext().getassets().open(localpath);                      log.d(tag, "shouldinterceptrequest: localpath " + localpath);                      string mimetype = "text/javascript";                      if (localpath.endswith("css")) {                          mimetype = "text/css";                      }                      return new webresourceresponse(mimetype, "utf-8", is);                  } catch (ioexception e) {                      e.printstacktrace();                      return null;                  }              } else {                  return null;              }          }

3、增加错误页面展示限制

在onreceivederror方法中,通过 request.isformainframe() || url.equals(geturl() 判断来尽可能少的减少错误页面的展示。即当错误页面是主页面时才展示错误页,避免整个页面中如某个icon等展示错误,导致影响整个页面的情况【如网易音乐的某些url,就曾有出现这种情况,通过这种方式可以避免错误页面展示】。

          /**           * 此方法中加载错误页面的时候,需要判断下 isformainframe 是否为true 亦或者 当前url跟加载的url是否为同一个url。           *           * @param view           * @param request           * @param error           */          //android6.0之后的方法          @requiresapi(api = build.version_codes.m)          @override          public void onreceivederror(webview view, webresourcerequest request, webresourceerror error) {              super.onreceivederror(view, request, error);              if (build.version.sdk_int >= build.version_codes.m) {                  string url = request.geturl().tostring();                  int errorcode = error.geterrorcode();                  string description = error.getdescription().tostring();                  log.d(tag, "onreceivederror---> " + " url:" + url + "errorcode:" + errorcode + " description:" + description + " failingurl:" + url + " request.isformainframe():" + request.isformainframe());                  // 如果当前网络请求是为main frame创建的,则显示错误页                  if (request.isformainframe() || url.equals(geturl())) {                      showreceivederrorpage(view, error.geterrorcode(), error.getdescription().tostring(), request.geturl().tostring());                  }              }          }

4、解决页面白屏问题

当ssl证书无效时,会导致白屏问题,可在 onreceivedsslerror 方法中添加 handler.proceed();

可解决白屏问题: 

          /**           * 【解决白屏问题】           * 如ssl证书无效时调用           *           * @param view           * @param handler           * @param error           */          @override          public void onreceivedsslerror(webview view, sslerrorhandler handler, sslerror error) {              //此处处理可避免ssl证书无效的页面白屏              handler.proceed();              super.onreceivedsslerror(view, handler, error);              log.d(tag, "onreceivedsslerror---> error = " + error);          }

以上就是android webview基础应用详解的详细内容,更多关于android webview的资料请关注<计算机技术网(www.ctvol.com)!!>其它相关文章!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/addevelopment/975805.html

(0)
上一篇 2021年12月20日
下一篇 2021年12月20日

精彩推荐