Android WebView的使用方法(基础篇)

WebView的使用方法

在做原生 app和web交互的时候,需要实现两个部分的内容,Java调用JS内容和JS调用Java的内容。webView就是Android中用来加载H5页面或者其他的JS页面的。组件默认提供了两者进行交互的能力。
webview一般加载两类网页资源,一类是本地的html文件,一类是远程的html文件。当然也可以用来加载本地的图片。

1.加载本地html

WebView mWebView = (WebView) findViewById(R.id.wv1);
WebSettings mWebSettings = mWebView.getSettings();
mWebSettings.setJavaScriptEnabled(true);
mWebView.loadUrl("file:///android_asset/index.html");//工程目录assets index.html文件
mWebView.loadUrl("file:///android_asset/icon.png");//工程目录assets图片文件

2.加载远程的资源文件

mWebView.loadUrl("http://www.baidu.com");

加载资源的三种方式

webView加载资源的方式有 loadUrlloadDataLoadDataWithBase。三者的区别是:
1.LoadUrl:直接加载网页、图片并显示。
2. loadData :显示文字与图片内容。
数据里面不用有"#(goBack失效) % (页面找不到)\ ?(转换报错)"这四个字符,如果有的话可以用 %23, %25, %27, %3f代替。

String mimeType = "text/html";
String encoding = "utf-8";
String data = "<html>测试测试测试测试</html>";
mWebView.loadData(data,mimeType,encoding);

3. LoadDataWithBase:显示文字与图片内容(支持多个模拟器),baseUrl,这是个标志位,标志当前页面的key值,而historyUrl就是一个value值,在加载时,它会把baseUrl和historyUrl传到List列表中,当作历史记录来使用,当前进和后退时,它会通过baseUrl来寻找historyUrl的路径来加载historyUrl路径来加载历史界面,history所指向的必须是一个页面,并且页面存在于SD卡中或程序中(assets),loadDataWithBaseURL,它本身并不会向历史记录中存储数据,需要我们自己来实现历史记录的存储。

// SDK1.5本地文件处理(不能显示图片)
 MyWebView.loadData(URLEncoder.encode(data, encoding), mimeType, encoding);
        // SDK1.6及以后版本 
MyWebView.loadData(data, mimeType, encoding);
        // 本地文件处理(能显示图片)
mWebView.loadDataWithBaseURL(null, data, mimeType, encoding, null);

webView处理URL跳转(WebViewClient与WebChromeClient)

WebViewClient

就是帮助WebView处理各种通知、请求事件的
onPageStart
onPageFinish
onReceivedHttpAuthRequest
onLoadResource
onReceivedError//WEB页面加载错误时回调,这些错误通常都是由无法与服务器正常连接引起的。 handler.proceed(); 此处理可避免SSL证书无效的页面白屏
onReceivedHttpError//当服务器返回错误码时回调
shouldOverrideUrlLoading //进行重定向的判断跟处理
return true: 表示当前url已经加载完成,即使url还会重定向都不会再进行加载
return false: 表示此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。在必要位置添加判断即可
shouldInterceptRequest//实现资源预加载
有时候一个页面资源比较多,图片,CSS,js比较多,还引用了JQuery这种庞然巨兽,从加载到页面渲染完成需要比较长的时间,有一个解决方案是将这些资源打包进APK里面,然后当页面加载这些资源的时候让它从本地获取,这样可以提升加载速度也能减少服务器压力。
getWebResourceResponse//获取服务器资源

WebChromeClient

处理JS的对话框、网站图标、网站title、加载进度等等
onCloseWindow(关闭WebView)
onCreateWindow()
onJsAlert //拦截Alert弹框(WebView上alert无效,需要定制WebChromeClient处理弹出)
onJsPrompt
onJsConfirm //拦截 confirm弹框
onProgressChanged //获取网页加载进度
onReceivedTitle //获取网站标题 (Android 6.0 以下通过title获取【捕捉HTTP ERROR】)
onReceivedIcon //网站图标
onConsoleMessage //打印console信息
onPermissionRequest //该方法在web页面请求某个尚未被允许或拒绝的权限时回调

webView的缓存模式

1.LOAD_CATCH_ONLY//只读取本地缓存,不使用网络
2.LOAD_DEFAULT//根据catche-control来决定
3.LOAD_NO_CATCH//不使用缓存
4.LOAD_CATCH_ELSE_NETWORK//只要本地有,就访问本地的(不管是不是过期了或者no-cache)
//设置缓存模式

mWebSetting.setCacheMode(WebSettings.LOAD_DEFAULT);

最后需要清除缓存,包括WebView缓存数据库,缓存文件和缓存目录等等

Webview和JS交互

java调用JS

1、loadUrl(“javaScript:callJS)”)

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

2、evaluateJavascript(script,resultCallback)

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

JS调用原生Java

1、通过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);
        }
    }

2、通过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(协议名)来判读
     */
    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;
    }

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

// 是否支持页面中的js输入弹出框
 @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;
    }
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值