Android开发:聊聊WebView的使用
twbo5691
8年前
<p style="text-align:center"><img src="https://simg.open-open.com/show/494d25080467ae768fc5f720e889b676.jpg"></p> <p><strong>前言</strong></p> <p>尽管WebView是官方提供的控件,但使用使用起来依然是踩坑无数,想要获得一个较好的用户体验更是难上加难。接下来将重点说一下,个人在使用过程中总结出的一些经验和遇到的问题,希望能够对大家的开发带来一些帮助。</p> <p><strong>基本使用</strong></p> <pre> <code class="language-java">mWebView.loadUrl(url);</code></pre> <p>loadUrl() 如果只是单纯的想要显示一个静态网页的话,这样加载就足够了,但往往开发中,需要许多其他的设置,这就需要用到WebView 的 WebSettings。</p> <pre> <code class="language-java">WebSettings webSettings = mWebView.getSettings();</code></pre> <p>网页的交互是依赖于 JS 的,通过下面设置,可以开启 H5 网页的交互功能。</p> <pre> <code class="language-java">webSettings.setJavaScriptEnabled(true);</code></pre> <p>关于编译器会提示警告的问题,可以加入 @SuppressLint(“SetJavaScriptEnabled”) 来避免编译器的提示。</p> <ol> <li> <p>JS 与本地交互</p> <pre> <code class="language-java">mWebView.addJavascriptInterface(new JavaScriptInterface(this), "android");</code></pre> <p>将 对象注入到WebView 中,WebView 加载的网页均可调用该对象中的方法。"android" 为对象名。下面看一下对象的具体实现。</p> <pre> <code class="language-java">// 网页调动js方法 final class JavaScriptInterface { public JavaScriptInterface() { } @JavascriptInterface public void appRedirect(String url) { // 具体操作 } }</code></pre> <p>Android 从API17之后,提供注解 @JavascriptInterface ,也是为了避免出现安全隐患。</p> </li> <li>本地调用网页JS <pre> <code class="language-java">mWebView.loadUrl("javascript:appPayResultQuery()");</code></pre> 而 appPayResultQuery() 使用网页提供的JS方法。</li> </ol> <p>基本使用差不多这些就够了,接下来呢,重点说一下在开发工程中遇到的一些问题及原因,还有相应的解决方案。</p> <p><strong>使用过程中的问题及解决方案</strong></p> <ol> <li> <p>WebView 与 H5点击交互时,自动跳转到浏览器加载的问题</p> <p>WebView默认是使用第三方或系统默认浏览器打开网页,如果要避免该行为,使网页用WebView打开,覆盖该行为即可,如下操作:</p> <pre> <code class="language-java">mWebView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } });</code></pre> </li> <li> <p>证书引起的相关问题,例如:WebView 加载网页存在https协议时,证书认证失败。</p> <p>这里提供一种非常暴力的解决方法,如果WebView对于加载的网页的安全要求并不是很高的话,可以使用该方法。</p> <pre> <code class="language-java">mWebView.setWebViewClient(new WebViewClient() { @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed();//接受证书 } }); return view;</code></pre> </li> <li> <p>某些网页在Android 5.0及其以上的版本加载成功,图片却无法显示的问题,遇到这种情况的原因可能有很多,这里说一下我在遇到这种情况时的原因:该网页是https协议,而加载的图片是 http协议。解决方法呢,也简单:</p> <pre> <code class="language-java">private void setMinedContentMode(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); } }</code></pre> <p>该方法的解释是:</p> <p>当一个安全的来源(origin)试图从一个不安全的来源加载资源时配置WebView的行为。默认情况下,KITKAT及更低版本默认值为MIXED_CONTENT_ALWAYS_ALLOW,LOLLIPOP版本默认值MIXED_CONTENT_NEVER_ALLOW,WebView首选的最安全的操作模式为MIXED_CONTENT_NEVER_ALLOW ,不鼓励使用MIXED_CONTENT_ALWAYS_ALLOW。</p> </li> <li> <p>WebView 返回上一页失败,可能是当前页面是由重定向过来的,当返回到上一页时,又会重新重定向跳转到该页。如何解决呢?实际上我们可以通过调用JS来解决。</p> <pre> <code class="language-java">webview.loadUrl("javascript:window.history.back();");</code></pre> </li> <li> <p>WebView 播放视频的问题,当你播放了视频之后,返回上一界面,或者跳转到其他页面,你会发现,播放的视频声音还在播放。</p> <p>原因就是 WebView threads never stop!</p> <p>解决方法也很简单,在相应的生命周期中,对 WebView 进行相关的处理。由于WebView 本身占用着很多资源,当它离开屏幕的时候,也应该释放其占有的 CPU ,网络资源。</p> <pre> <code class="language-java">private void destroyWebView() { // if (mWebView != null) { mWebView.removeAllViews(); mWebView.destroy(); mWebView = null; } } private void pauseWebView() { // if (mWebView == null) { return; } mWebView.onPause(); } private void resumeWebView() { // if (mWebView == null) { return; } mWebView.onResume(); }</code></pre> <p>WebView 也提供了相应的方法,我们只需要在相应的生命周期中调用即可。</p> </li> </ol> <p><strong>总结</strong></p> <p>关于WebView的使用就说这么多,关于其他的拓展就留给大家去解决吧。如果有什么不对的地方请大家指出,或者有更好地解决方法,也请留言讨论吧。</p> <p> </p> <p>来自:http://www.jianshu.com/p/f4e73b864f6c</p> <p> </p>