服务器H5和android交互,Android WebView简单使用以及实现native与h5交互

一、WebView

谷歌提供的系统组件,用来加载和展现html网页,其采用webkit内核驱动,来实现网页浏览功能。

拥有load() URL和本地html文件。

// 云端 webView.loadUrl("https://www.baidu.com");

// 本地 webView.loadUrl("file:///android_asset/demo.html");

注意:

loadUrl()必须在主线程中执行。

加载在线网页地址是会用到联网permission权限的,所以需要在AndroidManifest.xml中写入下面代码申请权限:

打开本地html文件时,是不需要设置WebViewClient,对应的asstes目录的url为:file:///android_asset/xxxxx。

WebView基本设置

如果我们需要设置WebView的属性,是通过WebView.getSettings()获取设置WebView的WebSettings对象,然后调用WebSettings中的方法来实现的。

// 是否支持缩放,配合方法setBuiltInZoomControls使用,默认true

setSupportZoom(boolean support)

//是否需要用户手势来播放Media,默认true

setMediaPlaybackRequiresUserGesture(boolean require)

是否显示窗口悬浮的缩放控制,默认true

setDisplayZoomControls(boolean enabled)

是否允许访问WebView内部文件,默认true

setAllowFileAccess(boolean allow)

是否保存表单数据,默认false

setSaveFormData(boolean save)

// 设置页面文字缩放百分比,默认100%

setTextZoom(int textZoom)

。。。。。。

二、WebViewClient

WebViewClient主要辅助WebView执行处理各种响应请求事件的,比如:

onLoadResource(WebView view, String url)

在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。

public void onLoadResource(WebView view, String url) {

// TODO Auto-generated method stub

if (DEBUG) {

Log.d(TAG, " onLoadResource ");

}

super.onLoadResource(view, url);

}

onPageStarted(WebView view, String url, Bitmap favicon)

在页面加载开始时调用。

public void onPageStarted(WebView view, String url, Bitmap favicon) {

// TODO Auto-generated method stub

if (DEBUG) {

Log.d(TAG, " onPageStarted ");

}

if (url.endsWith(".apk")) {

download(url);//下载处理

}

super.onPageStarted(view, url, favicon);

}

onPageFinished(WebView view, String url)

在页面加载结束时调用。

onReceivedError(WebView view, int errorCode,String description, String failingUrl)

加载错误的时候会回调,在其中可做错误处理,比如再请求加载一次,或者提示404的错误页面

这里有四个参数:

WebView view:当前的WebView实例

int errorCode:错误码

String description:错误描述

String failingUrl:当前出错的URL

如加载返回错误时,重新加载错误页面:

mWebView.setWebViewClient(new WebViewClient(){

@Override

public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {

super.onReceivedError(view, errorCode, description, failingUrl);

mWebView.loadUrl("file:///android_asset/error.html");

}

});

shouldOverrideUrlLoading(WebView view, String url)

拦截 url 跳转,在里边添加点击链接跳转或者操作

public boolean shouldOverrideUrlLoading(WebView view, String url) {

//拦截某个URL,将其转换成其它URL可以在这里做

view.loadUrl(url);

return true;

}

在点击请求的是链接是才会调用,重写此方法返回true表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边。

比如,我们拦截所有包含“blog.csdn.net”的地址,将其替换成”www.baidu.com”:

public boolean shouldOverrideUrlLoading(WebView view, String url) {

if (url.contains("blog.csdn.net")){

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

}else {

view.loadUrl(url);

}

return true;

}

或者

mWebView.setWebViewClient(new WebViewClient(){

@Override

public boolean shouldOverrideUrlLoading(WebView view, String url) {

if (url.contains("blog.csdn.net")){

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

}

return false;

}

}

在利用shouldOverrideUrlLoading来拦截URL时,如果return true,则会屏蔽系统默认的显示URL结果的行为,不需要处理的URL也需要调用loadUrl()来加载进WebVIew,不然就会出现白屏;如果return false,则系统默认的加载URL行为是不会被屏蔽的,所以一般建议大家return false,我们只关心我们关心的拦截内容,对于不拦截的内容,让系统自己来处理即可。

shouldInterceptRequest(WebView view, String url)

在每一次请求资源时,都会通过这个函数来回调,比如超链接、JS文件、CSS文件、图片等,也就是说浏览器中每一次请求资源时,都会回调回来,无论任何资源!但是必须注意的是shouldInterceptRequest函数是在非UI线程中执行的,在其中不能直接做UI操作,如果需要做UI操作,则需要利用Handler来实现,该函数声明如下:

public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

return null;

}

该函数会在请求资源前调用,我们可以通过返回WebResourceResponse的处理结果来让WebView直接使用我们的处理结果。如果我们不想处理,则直接返回null,系统会继续加载该资源。 利用这个特性,我们可以解决一个需求:假如网页中需要加载本地的图片,我们就可以通过拦截shouldInterceptRequest,并返回结果即可 。

如下:

mWebView.setWebViewClient(new WebViewClient(){

@Override

public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

try {

if (url.equals("http://localhost/pic.png")) {

AssetFileDescriptor fileDescriptor = getAssets().openFd("drawable.jpg");

InputStream stream = fileDescriptor.createInputStream();

WebResourceResponse response = new WebResourceResponse("image/png", "UTF-8", stream);

return response;

}

}catch (Exception e){

Log.e(TAG,e.getMessage());

}

return super.shouldInterceptRequest(view, url);

}

});

当发现当前加载资源的url是我们自定义的http://localhost/pic.png时,就直接将本地的图片drawable.jpg作为结果返回。

onReceivedSslError(WebView view, SslErrorHandler handler,SslError error)

HTTPS协议是通过SSL来通信的,所以当使用HTTPS通信的网址(以https://开头的网站)出现错误时,就会通过onReceivedSslError回调通知过来,它的函数声明为:

public void onReceivedSslError(WebView view, SslErrorHandler handler, android.net.http.SslError error) {

handler.proceed();

}

WebView view:当前的WebView实例

SslErrorHandler handler:当前处理错误的Handler,它只有两个函数SslErrorHandler.proceed()和SslErrorHandler.cancel(),SslErrorHandler.proceed()表示忽略错误继续加载,SslErrorHandler.cancel()表示取消加载。在onReceivedSslError的默认实现中是使用的SslErrorHandler.cancel()来取消加载,所以一旦出来SSL错误,HTTPS网站就会被取消加载了,如果想忽略错误继续加载就只有重写onReceivedSslError,并在其中调用SslErrorHandler.proceed()

SslError error:当前的的错误对象,SslError包含了当前SSL错误的基本所有信息。

如加载SSL出错的网站((12306是通过Https协议来传输的,但是它的SSL证书是有问题的,所以我们就以12306网站为例))

mWebView.setWebViewClient(new WebViewClient(){

@Override

public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {

// 一定要注释掉!

// super.onReceivedSslError(view, handler, error);

handler.proceed();

Log.e(TAG,"sslError:"+error.toString());

}

});

mWebView.loadUrl("https://www.12306.cn/");

注意:当出现SSL错误时,WebView默认是取消加载当前页面,只有去掉onReceivedSslError的默认操作,然后添加SslErrorHandler.proceed()才能继续加载出错页面当HTTPS传输出现SSL错误时,错误会只通过onReceivedSslError回调传过来,而不会触发onReceivedError回调的。

WebViewClient其余函数

/**

* 在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次

*/

public void onLoadResource(WebView view, String url)

/**

* (WebView发生改变时调用)

* 可以参考http://www.it1352.com/191180.html的用法

*/

public void onScaleChanged(WebView view, float oldScale, float newScale)

/**

* 重写此方法才能够处理在浏览器中的按键事件。

* 是否让主程序同步处理Key Event事件,如过滤菜单快捷键的Key Event事件。

* 如果返回true,WebView不会处理Key Event,

* 如果返回false,Key Event总是由WebView处理。默认:false

*/

public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event)

/**

* 是否重发POST请求数据,默认不重发。

*/

onFormResubmission(WebView view, Message dontResend, Message resend)

/**

* 更新访问历史

*/

doUpdateVisitedHistory(WebView view, String url, boolean isReload)

/**

* 通知主程序输入事件不是由WebView调用。是否让主程序处理WebView未处理的Input Event。

* 除了系统按键,WebView总是消耗掉输入事件或shouldOverrideKeyEvent返回true。

* 该方法由event 分发异步调用。注意:如果事件为MotionEvent,则事件的生命周期只存在方法调用过程中,

* 如果WebViewClient想要使用这个Event,则需要复制Event对象。

*/

onUnhandledInputEvent(WebView view, InputEvent event)

/**

* 通知主程序执行了自动登录请求。

*/

onReceivedLoginRequest(WebView view, String realm, String account, String args)

/**

* 通知主程序:WebView接收HTTP认证请求,主程序可以使用HttpAuthHandler为请求设置WebView响应。默认取消请求。

*/

onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)

/**

* 通知主程序处理SSL客户端认证请求。如果需要提供密钥,主程序负责显示UI界面。

* 有三个响应方法:proceed(), cancel() 和 ignore()。

* 如果调用proceed()和cancel(),webview将会记住response,

* 对相同的host和port地址不再调用onReceivedClientCertRequest方法。

* 如果调用ignore()方法,webview则不会记住response。该方法在UI线程中执行,

* 在回调期间,连接被挂起。默认cancel(),即无客户端认证

*/

onReceivedClientCertRequest(WebView view, ClientCertRequest request)

三、WebChromeClient

主要辅助WebView处理Javascript的对话框、网站Logo、网站title、load进度等处理。

onCloseWindow(WebView window)

通知主程序关闭WebView,并从View中移除,WebCore停止任何的进行中的加载和JS功能。

onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg)

请求主程序创建一个新的Window,如果主程序接收请求,返回true并创建一个新的WebView来装载Window,然后添加到View中,发送带有创建的WebView作为参数的resultMsg的给Target。如果主程序拒绝接收请求,则方法返回false。默认不做任何处理,返回false

onJsAlert(WebView view, String url, String message,JsResult result)

当网页调用alert()来弹出alert弹出框前回调,用以拦截alert()函数

注意:

如果需要使网页中的confrim()、alert()、prompt()函数生效,需要设置WebChromeClient!

在使用onJsAlert来拦截alert对话框时,如果不需要再弹出alert对话框,一定要return true;在return false以后,会依然调用系统的默认处理来弹出对话框的

如果我们return true,则需要在处理完成以后调用JsResult.confirm()或者JsResult.cancel()来告诉WebView我们点中哪个按钮来取消程序对话框。否则再次点击按钮将会失败

onJsPrompt(WebView view, String url, String message,String defaultValue, JsPromptResult result)

当网页调用prompt()来弹出prompt弹出框前回调,用以拦截prompt()函数

onJsConfirm(WebView view, String url, String message,JsResult result)

当网页调用confirm()来弹出confirm弹出框前回调,用以拦截confirm()函数

onProgressChanged(WebView view, int newProgress)

通知程序当前页面加载进度

WebView view:当前WebView实例

int newProgress:当前的加载进度,值从0到100

onReceivedIcon(WebView view, Bitmap icon)

通知当前页面网站新图标

onReceivedTitle(WebView view, String title)

通知页面标题变化

onShowCustomView

WebView只是用来处理一些html的页面内容,只用WebViewClient就行了,如果需要更丰富的处理效果,比如JS、进度条等,就要用到WebChromeClient。

四、CookieSync

CookieManager

CookieManager是用来管理Cookie的,主要来管理cookie相关,提供如下API:

setAcceptCookie()

setCookie()

getCookie(String url);

removeSessionCookies();

hasCookies()

removeAllCookie()

CookieSyncManager

CookieSyncManagerl继承WebSyncManager,来管理同步cookie相关,主要有以下API:

resetSync()

stopSync()

sync()

syncFromRamToFlash()

checkInstanceIsAllowed()

实现cookie同步:

CookieManager cookieManager = CookieManager.getInstance();

// 接受服务器

cookie cookieManager.setAcceptCookie(true);

//移除之前的cookie

cookieManager.removeSessionCookie();

// 注入cookies

List cookies = getCookies(customCookies);

for (String cookie : cookies) {

cookieManager.setCookie(uri.getHost(), cookie);

}

// 同步cookie

CookieSyncManager.getInstance().sync();

五、缓存模式

webview缓存模式有5种,具体方式:

LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据

LOAD_DEFAULT: 根据cache-control决定是否从网络上取数据。

LOAD_CACHE_NORMAL: API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式

LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.

LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。

六、Native与JS相互调用

该模块是针对JsBridge进行封装的功能介绍:

Java调用js代码:

public void registerHandler(final String handlerName, final JsHandler handler) {

this.mWebView.registerHandler(handlerName, new BridgeHandler() {

public void handler(String data, CallBackFunction function) {

if(handler != null) {

handler.OnHandler(handlerName, data, function);

// data实际就是js返回的jsonString数据,本案例为了统一处理,data统一采用{code,msg ,data} 形式,

}

}

});

}

//先注册回调js的方法

mProgressBarWebView.registerHandlers(mHandlers, new JsHandler() {

@Override

public void OnHandler(String handlerName, String responseData, CallBackFunction function) {

if (handlerName.equals("callNative")) {

ToastUitl.showShort(responseData);

function.onCallBack("我在XXXX");

} else if (handlerName.equals("callJs")) {

ToastUitl.showShort(responseData);

// 想调用你的方法:

function.onCallBack("好的 这是图片地址 :xxxxxxx");

} if (handlerName.equals("open")) {

mfunction = function;

pickFile();

}

}

});

// 调用js

mProgressBarWebView.callHandler("callNative", "hello H5, 我是java", new JavaCallHandler() {

@Override

public void OnHandler(String handlerName, String jsResponseData) {

ToastUitl.showShort("h5返回的数据:" + jsResponseData);

}

});

js调用Native

public void callHandler(final String handlerName, String javaData, final JavaCallHandler handler) {

this.mWebView.callHandler(handlerName, javaData, new CallBackFunction() {

public void onCallBack(String data) {

if(handler != null) {

handler.OnHandler(handlerName, data);

}

}

});

}

// 注册一个"callNative"函数,用来接收java层的数据

bridge.registerHandler("callNative", function(data, responseCallback) {

document.getElementById("show").innerHTML = ("data from Java: = " + data);

var responseData = "hello java ! 我要你的地址!";

alert('JS say:'+ responseData);

// response层

responseCallback(responseData);

});

function onUrl() {

var data = "我要你一个url";

//call native method

window.WebViewJavascriptBridge.callHandler(

'callJs'

, {'param': data }

, function(responseData) {

alert('Js 收到你的地址:'+ responseData);

}

);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值