浅谈Hybrid

964 阅读6分钟
原文链接: my.oschina.net

Hybrid

一.了解Hybrid

词典上的翻译 就是混合体的意识 那么在移动开发中他就是Native+Web混合开发的意思

Hybrid

二.Native App、Web App、Hybrid App

对比图表

总结起来两句话:

纯Native的迭代太慢,不能动态更新,且不能跨平台

纯Web页,有很功能无法实现,有些动画效果实现其体验太差

因此我们需要Hybrid

ps:怎样判断一个App的页面是native的还是web的?

Android手机 设置->开发者选项->显示布局边界 即可

三.Web Native 如何通信

说Hybrid首先肯定是要从Web和Native图和通讯说起

Android里面

Android call JS 两种Api

  1. WebView loadUrl()

  2. WebView evaluateJavascript()

Android call JS

当你的App只需要支持4.4以上的手机的时候就用evaluateJavascript() 确实4.4一下的手机越来越少不到10%,否则老老实实loadurl()

JS call Android 三种Api

  1. addJavascriptInterface

  2. shouldOverrideUrlLoading()

  3. alert()、confirm()、prompt()

JS call Android

如果不需要考虑只有5%的人使用的4.2以下的手机果断addJavascriptInterface 需考虑ios统一问题就拦截Url 需要返回值拦截prompt()

最后因为考虑到版本兼容和ios统一的问题 我们最终选择的是loadUrl + shouldOverrideUrlLoading的方式

web2native详细讲述请点击

各种方式的详细使用Demo请点击我的GitHub

四.Hybrid框架设计

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

这就意味着分别是从网络获取|本地缓存获取|以及请求之后发现没有更新|再取本地

Hybrid

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可以做的更好

想做的更好就要解决这两个问题

  1. 缓存的时间不知道设置多长时间合适,设置的长了不能及时更新,设置的短了没有缓存的效果
  2. 304虽然不下载 但是有请求 也耗资源

我们已一个具体的例子来解释下

Hybrid

这是谁网上找到的应用案例,首先超时时间设置了半年,相当于可以不用考虑 同是根据资源的版本号,判断是否需要网络请求新版本的js

当然这样做的代价就是需要一个本地的资源与版本的映射关系,服务端也要=做好一个更新版本的管理后台。

这里参考了大牛的文章

2.H5缓存

是数据级的缓存 一共五种如下

Hybrid

所以相对的H5缓存是缓存在应用层上的实现

我们最终采用的是浏览器缓存+Dom storage的方式,其中dom storage用于存储一些数据,方便一些表单的重复提交

这里推荐一篇写的非常好的解释缓存的文章

六.统一页面跳转路由

最后我们聊聊页面的统一跳转,这个不是Hybrid必须的,但是可以解决大项目,复杂项目,组件化比较明显的项目

使各个Model 各种实现形式的页面之间解耦。

各种路由实现上大同小异,这里以Arouter为例简单解释,我们在搭建Hybrid框架的过程中,可以慢慢模仿实现,没必要全盘引入

这样既可以轻量,对自己也是一个提高。

首先是遇得到的痛点

  1. Native页面 WebView 浏览器外链 页面的实现形式太多,页面跳转不好管理,耦合性高
  2. 各modle间页面的相互唤起,尤其是低级model如何唤起上级model的activity
  3. 页面pv uv不好统一统计

Arouter

主要的功能点是:

  1. Native WebView 页面的统一跳转
  2. 外链、统一入口
  3. 业务降级
  4. 跳转拦截
  5. 声明使用简单
  6. 支持处理『未知页面』

解决了上面的用户痛点

具体的使用方法git上面写的很清楚了,这里就不赘述了。

Github地址

我们根据他的原理看看我们如何模仿着做一个轻量级的。

原理如图所示

Hybrid

在这里应用了JavaPoet在编译时对注解内容进行解析,行程对应关系类,在运行时生成页面映射信息,减少了运行时的开销。

当然我们自己的Hybrid前期可以简单的用注解和反射替代javaPoet,在运行时生成一个映射表,来起到相同的作用。


本文旨在给大家掀开hybrid的大门,了解Hybrid的整体思路,后续随着我们项目的不断完善,我会写一篇专门介绍Hybrid从0到1的文章,欢迎大家指教。