hybrid
本身的意思是混合的,其实用在这里,就是指的是原生和Web
开发混合起来,各展所长。
- 最近在做
Android
hybrid
方面的研究和开发。有一些关于WebView
开发的心得体会,特分享于大家。 - 之前我在这方面有两篇相关博客,分别介绍了Android中webview与javascript交互方法以及Android JS Debug技巧。这两篇文章对一些
WebView
的基本操作、使用以及调试进行了总结。 - 今天我会对在开发Web
离线包
遇到的问题、对webView
请求请求拦截以及调整
这些方面做介绍。
hybrid离线包
因为hybrid
方案使用webView
加载,所以速度上有点慢,我们采用在本地使用离线包的形式、这样加载来提升速度,从而不受网络的影响。
这样做就需要使用 file:///
协议来加载本地离线web
页面,这样使用起来发现会导致一个问题,服务端去拿存储进去的cookie
值,在大部分Android
手机和部分iPhone
手机拿不到,
|
|
经过分析,发现应该是因为协议的问题,我们用的是file:///
协议,而用http
协议就没有这个问题。
这样的话离线就遇到这样的问题,要么服务器端做一个兼容,不用cookie
,这样很麻烦。或者是使用JS调用原生方法,每一个网络请求都起客户端进行封装,这样也是要改动非常多。
最终发现webView
有这样一个方法shouldInterceptRequest
,这个方法会在每一个请求执行前,进行拦截,然后开发者可以任意处理后,再返回一个处理后的网络请求WebResourceResponse
,这个方法真是太酷了。
- 与是我们就可以将本地
file
协议先伪装成http
协议,先随便请求一个网络地址,这个地址是什么不重要,只要首页一样就行了
|
|
|
|
- 加载后,在此处进行拦截所有的请求,然后做处理,将所有的请求全部转换为本地文件
|
|
- 其中
WebResourceResponse
主要是由三个部分组成
|
|
其中 mimeType
为请求文件的类型、encoding
为文件的编码、data
为文件的inputStream
mimeType
这个可以根据文件后缀来映射,或者用第三方开源的工具,encoding
我们一般就用utf-8
,文件流就直接读取就行了。
例如这样读取:
|
|
- 这样就完美的将本地
web
页面file
协议请求伪装成了http
协议的请求,这样cookie的问题就解决了。
webView中的所有网络请求都要添加自定义header
- 肯定有很多产品会希望webView中的所有网络请求都要添加自定义header,但webView只提供了一种添加header的方法
|
|
但这种方法只能在url
中添加,其它页面中的请求就添加不上了,那怎么办呢?
此时我们一思考就会发现,用上面shouldInterceptRequest
这个拦截所有请求的方法就能解决这个问题。
我们在所有网络请求到达时,拦截,然后用http
请求的方法,先添加header,然后去请求这个文件流,然后返回组装成webView
需要的WebResourceResponse
是不是很赞,哈哈。
|
|
Cookie问题
- 在使用第三方微博登录时,发现当用户没有安装微博时,微博web端会在登陆成功后清除整个应用
webView
的cookie
,这个就导致此时我们的cookie
丢失,失效的问题,怎么解决呢? 其实仔细研究发现
webView
也为我们提供了非常有用的cookie设置和cookie读取问题我们可以首先要读取
cookie
,放在内存中
|
|
- 然后在微博将
cookie
清除后,将cookie
再保存进去12345678private void saveCookies() {if (!TextUtils.isEmpty(mCookie)) {CookieSyncManager.createInstance(mContext);CookieManager.getInstance().setAcceptCookie(true);CookieManager.getInstance().setCookie(LoginActivity.DAMAIN, mCookie);CookieSyncManager.getInstance().sync();}}
这样问题就方便地解决了。
总结
hybrid
是一种很好的方案,webView
提供的功能很强大,后续有更多有好的想法会持续分享给大家。- 这是一个种很好的方案,两个平台解决方案都是想通的,iOS里的这个方法叫
cachedResponseForRequest
.