Webview相关知识点

474 阅读4分钟

打开网页时不调用系统浏览器, 而是在本WebView中显示

mWebView.setWebViewClient(new WebViewClient(){
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
          view.loadUrl(url);
          return true;
      }
  });

通过java代码调用javascript

WebSettings webSettings =   mWebView .getSettings();       
webSettings.setJavaScriptEnabled(true); 
mWebView.addJavascriptInterface(new Object() {       
            public void clickOnAndroid() {       
                mHandler.post(new Runnable() {       
                    public void run() {       
                        webview.loadUrl("javascript:wave()");       
                    }       
                });       
            }       
        }, "demo");

WebView 加载界面主要调用三个方法:LoadUrl、LoadData、LoadDataWithBaseURL

  • LoadUrl 直接加载网页、图片并显示(本地或是网络上的网页、图片、gif)
  • LoadData 显示文字与图片内容
  • LoadDataWithBase 显示文字与图片内容(支持多个模拟器版本)

WebSettings 的常用方法介绍

  • setJavaScriptEnabled(true); //支持js
  • setPluginsEnabled(true); //支持插件
  • setUseWideViewPort(false); //将图片调整到适合webview的大小
  • setSupportZoom(true); //支持缩放
  • setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); //支持内容重新布局
  • supportMultipleWindows(); //多窗口
  • setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存
  • setAllowFileAccess(true); //设置可以访问文件
  • setNeedInitialFocus(true); //当webview调用requestFocus时为webview设置节点webview webSettings.setBuiltInZoomControls(true); //设置支持缩放
  • setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口 setLoadWithOverviewMode(true); // 缩放至屏幕的大小
  • setLoadsImagesAutomatically(true); //支持自动加载图片

WebViewClient 的方法全解

  • doUpdateVisitedHistory(WebView view, String url, boolean isReload) //(更新历史记录)
  • onFormResubmission(WebView view, Message dontResend, Message resend) //(应用程序重新请求网页数据)
  • onLoadResource(WebView view, String url) // 在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。
  • onPageStarted(WebView view, String url, Bitmap favicon) //这个事件就是开始载入页面调用的,通常我们可以在这设定一个loading的页面,告诉用户程序在等待网络响应。
  • onPageFinished(WebView view, String url) //在页面加载结束时调用。同样道理,我们知道一个页面载入完成,于是我们可以关闭loading 条,切换程序动作。
  • onReceivedError(WebView view, int errorCode, String description, String failingUrl)// (报告错误信息)
  • onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,String realm)//(获取返回信息授权请求)
  • onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) //重写此方法可以让webview处理https请求。
  • onScaleChanged(WebView view, float oldScale, float newScale) // (WebView发生改变时调用)
  • onUnhandledKeyEvent(WebView view, KeyEvent event) //(Key事件未被加载时调用)
  • shouldOverrideKeyEvent(WebView view, KeyEvent event)//重写此方法才能够处理在浏览器中的按键事件。
  • shouldOverrideUrlLoading(WebView view, String url) //在点击请求的是链接是才会调用,重写此方法返回true表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边。这个函数我们可以做很多操作,比如我们读取到某些特殊的URL,于是就可以不打开地址,取消这个操作,进行预先定义的其他操作,这对一个程序是非常必要的。

Webview调用Native

方法一 :通过WebView的addJavascriptInterface进行对象映射:

    mWebView.addJavascriptInterface(new JsCallAndroidInterface(), "JSCallBackInterface");

 	/**
     * JS调用android原生方法1:
     *
     * 通过WebView的addJavascriptInterface()进行对象映射
     */
    private class JsCallAndroidInterface {
 
        /**
         *@JavascriptInterface注解方法.
         * js端调用,4.2以后安全;4.2以前,当JS拿到Android这个对象后,
         * 就可以调用这个Android对象中所有的方法,包括系统类(java.lang.Runtime 类)
         * 从而进行任意代码执行。
         * @param msg
         */
        @JavascriptInterface
        public void callback(String msg) {
            ToastUtil.showToast(APIWebViewActivity.this, "JS方法回调到web了 :" + msg);
        }
    }

方法二 :通过WebViewClient shouldOverrideUrlLoading方法回调拦截url:

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (resolveShouldLoadLogic(url)) {
        return true;
    }
    return super.shouldOverrideUrlLoading(view, url);
}

	/**
     * JS调用android原生方法2:
     *
     * 通过WebViewClient shouldOverrideUrlLoading方法回调拦截url
     *
     * 根据协议的参数,判断是否是所需要的url:
     * 一般根据scheme(协议格式),authority(协议名)来判读
     *
     * @param url
     * @return
     */
    private boolean resolveShouldLoadLogic(String url) {
        Uri uri = Uri.parse(url);
        if (uri.getScheme().equals("js")) {
            if (uri.getAuthority().equals("Authority")) {
                ToastUtil.showToast(APIWebViewActivity.this, "方法2");
            }
            return true;
        }
        return false;
    }

方法三 :通过WebChromeClient的 onJsPrompt()等方法 ,回调拦截JS对话框prompt()等:

/**
* 是否支持页面中的js输入弹出框
*
* @param view
* @param url
* @param message
* @param defaultValue
* @param result
* @return
*/
  @Override
  public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
                            JsPromptResult result) {
  if (resolveJSPrompt(message)) {
    return true;
  }
  return super.onJsPrompt(view, url, message, defaultValue, result);
}

/**
  * JS调用android原生方法3:
  *
  * 通过WebChromeClient的 onJsAlert() onJsConfirm() onJsPrompt() 方法
  * 回调拦截JS对话框alert() confirm() prompt()
  */
  private boolean resolveJSPrompt(String message) {
      Uri uri = Uri.parse(message);
      if (uri.getScheme().equals("js")) {
          if (uri.getAuthority().equals("Authority")) {
              ToastUtil.showToast(APIWebViewActivity.this, "方法3");
          }
          return true;
      }
      return false;
  }

Native调用Webview

方法一 :loadUrl("javascript:callJS()") 此方法简洁、效率低。当不需要返回值且对性能要求较低时可以考虑使用:

/**
* Native调用JS方法一:
* 方法简洁、效率低
* 当不需要获取返回值且对性能要求较低时可选择使用。
*/
webView.loadUrl("javascript:callJS()");

方法二 :evaluateJavascript(script,resultCallback):需4.4及以上才可使用,效率高且有返回值:

/**
 * Native调用JS方法二:
 * 效率高,有返回值(4.4以上系统使用)
 */
webView.evaluateJavascript("javascript:callJS('yao')", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String value) {
        //此处为JS返回的结果
        Log.d("value:" + value);
    }
});