作为盛行已久的开发方式,Hybrid的相关介绍已经是相当普遍了。不过看到博客园里基本上都是从android或者ios的角度来讲解的,对于h5的前端来说看起来只能是一直半解。感觉有必要从前端的角度来理解和解读一下Hybrid相关内容。作为移动开发技术中不可或缺的一项,Hybrid 凭借其特有的优势牢牢的占据了一席之地。这里就不展开讨论讨论Hybrid的优劣了(想了解请查看http://www.cnblogs.com/yexiaochai/p/4921635.html

   html作为一种解释性语言,需要运行于解释器之上。我们常用的的pc端浏览器就是其一。作为移动端的一种混合开发的模式,Hybrid是如何解决这一问题的呢。这就引出了webview这一概念。hybride中的h5依托于webview容器来(对应于ios和安卓,应该有不同实现,这里就不是前端可以细说的了)解释运行。下面就看一下webview相关的部分。

  一、webview的概念:

  先放一段基本定义:A View that displays web pages. This class is the basis upon which you can roll your own web browser or simply display some online content within your Activity. It uses the WebKit rendering engine to display web pages and includes methods to navigate forward and backward through a history, zoom in and out, perform text searches and more.
        自己的理解:webview用来展示网页的view组件,该组件是你运行自己的浏览器或者在你的线程中展示线上内容的基础。使用webkit渲染引擎来展示,并且支持前进后退等基于浏览历史,放大缩小,等更多功能。
      简单来说WebView是手机中内置了一款高性能 webkit 内核浏览器,在 SDK 中封装的一个组件。不给过没有提供地址栏和导航栏,只是单纯的展示一个网页界面。

  作为hybrid中的webview,相比较于native中原生组件,给人最直观的印象可能就是慢,不给过为什么这么慢呢,当然影响因素是很多的,除去一些外部因素。与webview自身的初始化和加载过程也是分不开的 ,下面来看一下webview的初始化过程

  二、webview初始化

  当App首次打开时,默认是并不初始化浏览器内核的;只有当创建WebView实例的时候,才会创建WebView的基础框架。所以与浏览器不同,App中打开WebView的第一步并不是建立连接,而是启动浏览器内核。

  在浏览器中,我们输入地址时(甚至在之前),浏览器就可以开始加载页面。

  在客户端中,客户端需要先花费时间初始化WebView完成后,才开始加载。

  而这段时间,由于WebView还不存在,所有后续的过程是完全阻塞的。简单对比下两个的渲染过程:

浏览器:

      

       webview:

  可以看出在webview初始化之前,后面的步骤根本无从走起,耗时当然变长了。并且每次打开webview都要走这个过程。

  三、Webview优化

  从上面可以看出来webview相对浏览器来说,影响点在于webview的初始化并且阻塞后面action的这个过程,其实说来也简单(我只是说概念上,native的东西对我来说还是很难的)对应问题的两种表现形式,对应有两个方向上的优化。
  3.1、减少webview初始化的消耗

  鉴于每次打开都要进行初始化webview组件的这种场景,很自然的对应起来一种设计模式即单例模式,既然每次都要走相同步骤完全可以实例化一个全局对象,从而免去其他过程的消耗。当然客户端的同学们也是这样做的: 初始完全可以建一个全局,隐藏的webview。以供使用。省去了每次的初始化过程。

不过这样的缺点也是有的,就看如何取舍了:
  1、内存消耗:毕竟这货一直存在
  2、页面间的跳转:毕竟只有一个webview实例,每次不同的加载需要处理的情况就比较多了。

  3.2、针对阻塞的过程
  每次的阻塞加载过程等待时间消耗也是很大的,就看能不能将串行的过程并行化。不过对于webview来说只能是这个样子,不过我们需要跳出仅仅局限于webview的视线,webview仅仅是移动系统的一个组件,统计存在其他组件,网络请求的过程完全可以交给native来做,也正如native一直在做的一样,完全是可以处理该过程的。例如后端同学经常要开发的mapi,就是针对native的接口。

  四、webview与native的交互

  上面提到native可以并行执行网络请求,以加快webview的呈现时间。又一个问题出现了,webview如何调用native接口去请求数据并获取native拿到的数据呢。除此之外还涉及到调用底层api等需求都需要借助native实现,问题的核心就是两者的交互如何实现,作为两者之间的沟通桥梁,jsbridge就应运而生了。
  所谓交互无外乎两大块:一是h5调用native,另一个是native调用h5。
  一、Native调用JS:

  原生调用h5比较简单,可以直接调用。毕竟这里存在一个宿主的关系,脱离了webview,js就没有生命力了,而native其他功能是在webview外部的。所以反过来不能直接调用。
  例如有如下代码:

 <script type="text/javascript">
function myFunc() {
return "Text from web"
}
</script>

  ios可以直接通过webview的属性调用(前端只能从方法名来看了,将js代码当做字符串读出来再解析)

NSString * result = [self.webView stringByEvaluatingJavaScriptFromString:@"myFunc()"];

  2.H5网页的JS调用Native

  本质还是用uiwebview的代理方法进行字段拦截(判断url的scheme),实现js间接调用native的method。

  android可以直接给网页中js函数注入一个原生代码接口。

 //相当于添加一个js回调接口可以直接通过window全局对象调用对应接口了:
mWebView.addJavascriptInterface(this, "native");
<button onClick="window.native.actionFromJs()">点击调用Native代码</button>

  ios说起来也是注入只不过没有android那么方便。
      在 webView 的 delegate 的 - (void)webViewDidFinishLoad:(UIWebView *)webView 里用下边的方式注入 JavaScript

 NSString *js = @"(function() {\
window.JSBridge = {};\
window.JSBridge.callFunction = function(functionName, args){\
var url = \"bridge-js://invoke?\";\
var callInfo = {};\
callInfo.functionname = functionName;\
if (args)\
{\
callInfo.args = args;\
}\
url += JSON.stringify(callInfo);\
var rootElm = document.documentElement;\
var iFrame = document.createElement(\"IFRAME\");\
iFrame.setAttribute(\"src\",url);\
rootElm.appendChild(iFrame);\
iFrame.parentNode.removeChild(iFrame);\
};\
return true;\
})();";
[webView stringByEvaluatingJavaScriptFromString:js];

  以前端的角度来看这段代码,是在 window 里创建一个叫 JSBridge 的对象,然后在里边定义一个方法 callFunction,

  这个方法的作用是把两个参数打包为 JSON 字符串,然后附带到我们自定义的 URL bridge-js://invoke? 后边,

  最后用 IFRAME 的方式来加载这个 URL当加载 IFRAME 的时候,就会调用 webView 的 delegate 的

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 

(即特定方法来处理)方法。对url进行处理,把以约定字符开头的url后面的json解析出来,执行对应方法。

至此webview与native的交互即jsbridge的实现从前端的角度也大概就是这样子结束了,关于上面的客户端代码可以自行研究,不给过前端来看也是不太难看懂。以上就是我对webview的理解了,欢迎大家相互交流共同进步。

参考文章:WebView性能、体验分析与优化

     浅谈Hybrid技术的设计与实现

 

前端解读Webview的更多相关文章

  1. 前端解读控制反转(IOC)

    前言 随着前端承担的职责越来越重,前端应用向着复杂化.规模化的方向发展.大型项目模块化是一种趋势,不可避免模块之间要相互依赖,此外还有很多第三方包.这样的话如何去管理这些繁杂的文件,是一个不可避免的话 ...

  2. 前端解读面向切面编程(AOP)

    前言 面向对象(OOP)作为经典的设计范式,对于我们来说可谓无人不知,还记得我们入行起始时那句经典的总结吗-万事万物皆对象. 是的,基于OOP思想封装.继承.多态的特点,我们会自然而然的遵循模块化.组 ...

  3. 谈一谈前端多容器(多webview平台)处理方案

    文中是我个人的一些开发经验,希望对各位有用,也希望各位多多支持讨论,指出文中不足以及提出您的一些建议. 双容器 得益于近几年移动端的发展,前端早已今非昔比,从大型框架来说angularJS.react ...

  4. Android launchMode SingleTask newIntent 的问题

    前置条件 项目中,采用 MainActivity + 3个 fragment 的模式作为主要框架.MainActivity 使用 singleTask 模式启动.Fragment 采用 show/hi ...

  5. CORS跨域模型浅析及常见理解误区分析

    CORS跨域资源共享是前后端跨域十分常用的一种方案,主要依赖Access-Control-Allow(ACA)系列header来实现一种协商性的跨域交互. 基本模型 其中的具体流程大致可以分为以下几步 ...

  6. Mustache.js前端模板引擎源码解读

    mustache是一个很轻的前端模板引擎,因为之前接手的项目用了这个模板引擎,自己就也继续用了一会觉得还不错,最近项目相对没那么忙,于是就抽了点时间看了一下这个的源码.源码很少,也就只有六百多行,所以 ...

  7. 前端webview开发中遇到的一些问题及其解决方法

    最近做了一个webview中的兑换页面,本来以为很简单,想不到遇到了远远超出预期数量的BUG,记下来,以备后患. 1 inline-block元素折行 BUG描述:现在我有三个DIV,要在一列等宽排列 ...

  8. 代码解读 | VINS 视觉前端

    本文作者是计算机视觉life公众号成员蔡量力,由于格式问题部分内容显示可能有问题,更好的阅读体验,请查看原文链接:代码解读 | VINS 视觉前端 vins前端概述 在搞清楚VINS前端之前,首先要搞 ...

  9. 葡萄城首席架构师:前端开发与Web表格控件技术解读

    讲师:Issam Elbaytam,葡萄城集团全球首席架构师(Chief Software Architect of GrapeCity Global).曾任 Data Dynamics.Inc 创始 ...

随机推荐

  1. iOS 生成随机字符串 从指定字符串随机产生n个长度的新字符串

    随机字符串 - 生成指定长度的字符串 -(NSString *)randomStringWithLength:(NSInteger)len { NSString *letters = @"a ...

  2. Jmeter3.0新特性

    2016-5-19昨日,Jmeter又更新了新版本. 那么新版本有哪些新特性呢? Changes   This page details the changes made in the current ...

  3. javaWeb学习总结(4)- HttpServletResponse

    一.简介: Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象. request和response对象即然代表请求和 ...

  4. JVM、GC与HashMap

    阿里巴巴突然来了个面试邀请电话,问了些java底层的东西,不知所措,所以专门花了些时间做了下学习,顺便记录下,好记性不如烂笔头. 一.对JAVA的垃圾回收机制(GC)的理解 不同于C/C++需要手工释 ...

  5. 选择排序——Python实现

    选择排序: 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理如下.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小( ...

  6. iOS bug调试技巧学习----breakpoint&condition

    给断点添加条件 - (void)testCondition2 { NSArray *array = @[@"我们", @"一起", @"来" ...

  7. iOS自定义弹出视图

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #78492a } p.p2 { margin: 0.0px 0. ...

  8. MVC架构简介及其测试策略

    最近在WEB端测试工作中陷入了瓶颈,单纯的手动功能测试在没有成熟的代码规范之前还是很容易坑的,WEB自动化测试一时半会还没有什么进展,所以决定先学习一下网站用的MVC架构,跟着教程写了一个小网站,大概 ...

  9. 浏览器未安装flash插件,js判断直接去官网安装

    近期做了个活动页,里面根据需求插入了阿里云的视频,常见的浏览器都支持包括低版本的. 由于浏览器的更新换代很多版本放弃了flash的插件安装,火狐就是其中之一. 未安装flash的浏览器如果打开这个链接 ...

  10. 工程师倾情奉献-Win7 ISO 精简操作说明

    1.前提条件 a)本文档内容只适用于32bit win7 install ISO,其它OS不能保证兼容 b)示范文件为win7-ultimate-rtm-32-en-us-rdvd.iso 2.准备待 ...