一.了解Hybrid
词典上的翻译 就是混合体的意识 那么在移动开发中他就是Native+Web混合开发的意思
二.Native App、Web App、Hybrid App
总结起来两句话:
纯Native的迭代太慢,不能动态更新,且不能跨平台
纯Web页,有很功能无法实现,有些动画效果实现其体验太差
因此我们需要Hybrid
ps:怎样判断一个App的页面是native的还是web的?
Android手机 设置->开发者选项->显示布局边界 即可
三.Web Native 如何通信
说Hybrid首先肯定是要从Web和Native图和通讯说起
Android里面
Android call JS 两种Api
WebView loadUrl()
WebView evaluateJavascript()
当你的App只需要支持4.4以上的手机的时候就用evaluateJavascript()
确实4.4一下的手机越来越少不到10%,否则老老实实loadurl()
JS call Android 三种Api
addJavascriptInterface
shouldOverrideUrlLoading()
alert()、confirm()、prompt()
如果不需要考虑只有5%的人使用的4.2以下的手机果断addJavascriptInterface
需考虑ios统一问题就拦截Url
需要返回值拦截prompt()
最后因为考虑到版本兼容和ios统一的问题
我们最终选择的是loadUrl + shouldOverrideUrlLoading的方式
四.Hybrid框架设计
Hybrid设计无非就是要考虑如下的几件事情
如图是我们刚刚起步的Hybrid框架开发
支持组件调用(如吐司,dialog 进度条等等),支持方法调用
就是把通过shouldOverrideUrlLoading拦截到的url进行封装解析的过程。
缓存前期可以用系统自带的缓存,当然想要更灵活我们可以自己搞一套,详见下面的Cache部分。
页面的统一跳转意思就是在我们App开发完之后,js可以跳转到已经有的任意页面,这就需要一个好的路由配置,可以仿造Arouter
自己开发一个轻量级的页面路由功能,解耦页面间的跳转。
拓展和复用就不用我多说了,这里面肯定有一个循序渐进的过程。
五.Cache
Android的网页缓存有两种
1.浏览器缓存
就是所有的浏览器都支持的缓存,是页面级的缓存。
根据协议头中的参数定义的缓存Cache-Control(或 Expires)和 Last-Modified(或 Etag)。
所以说浏览器缓存是缓存在协议层上的实现。
下面是58同城M站首页随便的一个js,我们看到他设置的是600秒也就是十分钟的缓存时间,
而上次更新时间确实16年5月20号。我们分别记录了第一次访问,第二次访问,和十分钟后的第三次访问。
我们看到Status code 分别是 200|200(from disk cache)|304
这就意味着分别是从网络获取|本地缓存获取|以及请求之后发现没有更新|再取本地
Android这边可以根据Api控制webview的浏览器缓存策略。
WebSettings webSettings= webView.getSettings();
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
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,都使用缓存中的数据。
上面的缓存机制可以基本满足我们WebApp的需求,但是我们的Hybrid可以做的更好
想做的更好就要解决这两个问题
- 缓存的时间不知道设置多长时间合适,设置的长了不能及时更新,设置的短了没有缓存的效果
- 304虽然不下载 但是有请求 也耗资源
我们已一个具体的例子来解释下
这是谁网上找到的应用案例,首先超时时间设置了半年,相当于可以不用考虑
同是根据资源的版本号,判断是否需要网络请求新版本的js
当然这样做的代价就是需要一个本地的资源与版本的映射关系,服务端也要=做好一个更新版本的管理后台。
2.H5缓存
是数据级的缓存 一共五种如下
所以相对的H5缓存是缓存在应用层上的实现
我们最终采用的是浏览器缓存+Dom storage的方式,其中dom storage用于存储一些数据,方便一些表单的重复提交
六.统一页面跳转路由
最后我们聊聊页面的统一跳转,这个不是Hybrid必须的,但是可以解决大项目,复杂项目,组件化比较明显的项目
使各个Model 各种实现形式的页面之间解耦。
各种路由实现上大同小异,这里以Arouter为例简单解释,我们在搭建Hybrid框架的过程中,可以慢慢模仿实现,没必要全盘引入
这样既可以轻量,对自己也是一个提高。
首先是遇得到的痛点
- Native页面 WebView 浏览器外链 页面的实现形式太多,页面跳转不好管理,耦合性高
- 各modle间页面的相互唤起,尤其是低级model如何唤起上级model的activity
- 页面pv uv不好统一统计
Arouter
主要的功能点是:
- Native WebView 页面的统一跳转
- 外链、统一入口
- 业务降级
- 跳转拦截
- 声明使用简单
- 支持处理『未知页面』
解决了上面的用户痛点
具体的使用方法git上面写的很清楚了,这里就不赘述了。
我们根据他的原理看看我们如何模仿着做一个轻量级的。
原理如图所示
在这里应用了JavaPoet在编译时对注解内容进行解析,行程对应关系类,在运行时生成页面映射信息,减少了运行时的开销。
当然我们自己的Hybrid前期可以简单的用注解和反射替代javaPoet,在运行时生成一个映射表,来起到相同的作用。
本文旨在给大家掀开hybrid的大门,了解Hybrid的整体思路,后续随着我们项目的不断完善,我会写一篇专门介绍Hybrid从0到1的文章,欢迎大家指教。