赞
踩
在做原生 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处理各种通知、请求事件的
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//获取服务器资源
处理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页面请求某个尚未被允许或拒绝的权限时回调
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缓存数据库,缓存文件和缓存目录等等
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);
}
});
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; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。