hybrid简单了解

技术点总有它的来由。javascript

文章概要:css

  • 1.hybrid 基本概念
  • 2.前端和客户端的交互
  • 3.前端和客户端的交互实现
  • 4.前端交互实现关注点
  • 5.小结

 1.hybrid 基本概念

⑴.什么是hybrid?html

hybrid即“混合”,前端和客户端的混合开发模式,某些环节也可能涉及到 server 端。 hybrid 底层依赖于Native提供的容器(WebView),上层使用html&css&JS作业务开发。前端

⑵.webview是什么?java

app中的一个组件,相似于小型浏览器内核。native提供的容器盒子,用于加载h5页面。ios

图中表示了两种h5页面资源运用的方式
   ①以静态资源打包到app内的方式。
    前端将代码提供给native,native客户端拿到前端静态页面,以文件形式存储在 app 中。这种模式,若是前端静态页面须要更新,客户端就须要去server端下载静态资源,即客户端每次打开须要去线上检查有无更新包有就下载压缩包,解压更新静态资源。
 优势:由于资源在本地,经过file 协议读取,读取速度很是快,且能够作到断网模式下页面合理的展现。
  • 这样就涉及到了一个server端静态资源包管理系统。
  • 同时H5的资源是静态的存储在native本地,以file的方式读取,那么H5向远端发起的请求就存在跨域,因此H5的请求须要通过native作一层代理转发。
  • 静态资源越多native包就越大(因此这种模式更适用于,产品功能稳定,体验要求又高,且迭代频繁的场景)。
   ②以线上url方式(更偏H5)
 将资源部署在线上,native打开一个新的webview请求线上资源展现(同在浏览器中输入url,查看页面过程一致)
 优势:按需加载,用户使用到的页面才会更新,发请求能够不通过native作代理。
  • 不可避免请求线上资源,都须要时间,因此会出现瞬间白屏(弱网模式特别明显)。
  • 断网模式下没有内容显示。
  ③两种模式资源加载
  本地读取:
    
    线上读取:
    
 

(3).hybrid存在的意义?git

能够快速迭代开发更新。(无需app审核,哈哈由于对手机的操做权限不高?,相对于app)github

hybrid开发效率高,低成本,跨平台,ios和安卓共用一套h5代码。(ios和安卓接口一致)web

hybrid从业务开发上讲,没有版本问题,有BUG能及时修复(相对于app)。chrome

 2.前端和客户端的通信

native提供的容器盒子,用于加载h5页面,那么h5的页面要怎么跟native交互?

前端和客户端的交互大概描述:

  • JS访问客户端的能力,传递参数和回调函数。
  • 客户端经过回调函数返回内容。

前端的页面跟native交互,是经过schema协议。(事实上Native能捕捉webview发出的一切请求,这个协议的意义在于能够在浏览器中直接打开APP)

⑴.什么是schema协议?

大概描述 :scheme是一种页面内跳转协议,经过定义本身的scheme协议,native 拦截这个请求,能够很是方便跳转app中的各个页面。 

经过执行如下操做支持自定义URL方案:

  • 定义应用程序schema URL的格式。
  • 注册应用程序schema URL方案,以便系统将适当的URL定向到应用程序。
  • 应用程序处理收到的网址URL。

一些URL Scheme 

https://www.zhihu.com/question/19907735

截取一端代码,代码来源:https://github.com/tcoulter/jockeyJS/blob/master/JockeyJS/JS/jockey.JS

// 这段代码主要功能是前端经过一个特殊的协议给客户端发消息,客户端拦截请求而后处理
dispatchMessage: function(type, envelope) {
    // We send the message by navigating the browser to a special URL.
    // The iOS library will catch the navigation, prevent the UIWebView
    // from continuing, and use the data in the URL to execute code
    // within the iOS app.

var src = "jockey://" + type + "/" + envelope.id + "?" + encodeURIComponent(JSON.stringify(envelope)); var iframe = document.createElement("iframe"); iframe.setAttribute("src", src); document.documentElement.appendChild(iframe); iframe.parentNode.removeChild(iframe); iframe = null; }

⑵.具体H5与Native通讯,JS to native?

JS与Native通讯通常都是建立这类URL被Native捕获处理。

.native到h5页面,native to JS

native提供的容器盒子那么native,能否调用它提供的webview中window对象的方法了?

native 能够 调用以前跟前端约定好的挂载在window对象上面的方法。(具体实现了?)

                                                                          (图片来源点击)

/ Send an event to JavaScript, passing a payload.
// payload can be an NSDictionary or NSArray, or anything that is serializable to JSON.
// It can be nil.
[Jockey send:@"event-name" withPayload:payload toWebView:webView];

// If you want to send an event and also execute code within the iOS app when all
// JavaScript listeners have finished processing.
[Jockey send:@"event-name" withPayload:payload toWebView:webView perform:^{
  // Respond to callback.
}];

 

 3.前端和客户端的交互实现

 前端与Native两种交互形式:

① URL Schema(前端先定义对象,以及交互方法)

② 客户端定义对象,注入全局变量(Android自己就支持相似的实现,因此此处讨论ios的JavaScriptCore )

JavaScriptCore是一个C++实现的开源项目。使用Apple提供的JavaScriptCore框架,能够在Objective-C或者基于C的程序中执行Javascript代码,也能够向JavaScript环境中插入一些自定义的对象。JavaScriptCore从iOS 7.0以后能够直接使用,资料:https://developer.apple.com/documentation/javascriptcore。

⑴.URL Schema(前端先定义对象,以及交互方法)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
    <title>Document</title>
</head>
<body>
    <button id="btn1">扫一扫</button>
    <script type="text/javascript">
        function send(type, payload,callback) {
            var envelope = {
                id: id,
                type: type,
                host: host,
                payload: payload
            };
            window.myapp.[envelop.id] = callback;
            var src = "myapp://"+envelope.id + "?" + encodeURIComponent(JSON.stringify(envelop));
            //告诉客户端此时调用的函数, 函数执行完成后,告诉h5执行window.myapp.[envelop.id]这个函数。
       // host 加入使得客户端更容易控制是否响应和处理(毕竟app内可能有需求内嵌第三方页面)
var iframe = document.createElement("iframe"); iframe.setAttribute("src", src); document.documentElement.appendChild(iframe); iframe.parentNode.removeChild(iframe); iframe = null; } document.getElementById('btn1').addEventListener('click', function () { send("scan", {}, (payload) => { console.log("hi") }) }) </script> </body> </html>

 一般代码实现会把send函数部分进行封装,前端只须要实现与native约定的功能函数。

getPort: function() {
    window.send("getPort", {}, (payload) => {

    });
},
login: function(args = {}) {
    window.send("login", args, (payload) => {

    });
},

⑵.客户端定义对象,注入全局变量(客户端注入全局变量,供h5使用)

// 页面调用了未声明方法,事实上是Native注入给window对象的。(native在本地实现了js方法并注入h5)
// 在页面加载完成前注入全局变量myapp,myapp下面的方法,即app提供的API方法 myapp.getPort(data, (payload)
=> { }); myapp.login(data, (payload) => { });

两种方式的区别,由客户端仍是由h5预先定义对象,以及交互方法 。

 4.前端交互实现关注点

 代码来源:https://github.com/tcoulter/jockeyJS/blob/master/JockeyJS/JS/jockey.JS(如下代码例子,以URL Schema方式为基础)

⑴.导航栏的设置

导航栏一般是native实现,有回按钮退防止页面假死,即页面卡死能够回退。

同时native须要提供API供h5进行简单的定制(好比有的须要关闭按钮,分享按钮,收藏按钮等)

setBarBack() {
    Jockey.send("setBarBack", {
        "bar": {
            "position": "left",
            "cliekEvent": "onBack",
        }
    }); 
    // 取消监听onBack事件
    Jockey.off('onBack');
    // 监听onBack事件
    Jockey.on('onBack', () => {
        history.back()
    });
},

⑵.跳转是Hybrid必用API之一,对前端来讲有如下跳转:

① H5跳转Native界面

② H5新开Webview跳转H5页面。

用native的方法来跳转,通常是为了作页面的动画切换。

 如图咱们一般只会使用到导航栏下面部分,但咱们关注页面的导航栏,H5端能够注册事件监听native的导航栏的事件(非必须)

⑶.获取基本信息

在具有用户体系的模式下,H5页面能从native拿到基本的登陆信息,Native自己就保存了用户信息,提供接口给h5使用。

function getInfo() {
    return new Promise((resolve, reject) => {
        Jockey.send("getInfo", {}, (payload) => {
        
        });
    });
},

⑷.调用native原生具有的功能

相机,手机页面横屏显示或者竖屏显示等。

⑸.关于调试

Android:输入chrome://inspect/#devices便可(前提native打开了调试模式),固然Android也可使用模拟器,但与Android的真机表现过于不同,仍是建议使用真机测试。

iOS:需一台Mac机,而后打开safari,在偏好设置中将开发模式打开,而后点击打开safari浏览器,查看菜单栏开发菜单(前提native打开了调试模式)...

 

 5.小结

文章只是一个对hybrid的简单了解,文中例子比较粗糙,理解不许确之处,还请教正。对于有兴趣深刻了解Hybrid技术的设计与实现前端部分细节的能够看看参考资料~~

 

 

参考资料:

http://www.cnblogs.com/yexiaochai/p/4921635.html

http://www.cnblogs.com/yexiaochai/p/5524783.html

http://www.cnblogs.com/yexiaochai/p/5813248.html

相关文章
相关标签/搜索