Android WebView的使用方法(基础篇)
最近在看混合开发相关的东西,所以记录一下webview的使用
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加载资源的方式有 loadUrl,loadData和LoadDataWithBase。三者的区别是:
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)