注:因为不了解Dart,所以本文不对flutter相关内容进行阐述, 实在抱歉

其实写这篇文章的时候,我就知道,肯定有人问我:为什么不写flutter?抱歉了,flutter的大名我当然知道,可我只是一个写JS的,同时了解一些Java的知识,而flutter采用的编程语言,我暂时没有碰过,所以自然不敢妄加猜度,还请谅解

Hybrid

Hybird是一种混合开发应用,可以实现JS和Java代码的互通,单纯使用ios/android原生实现,开发进度和成本受不了,而单纯使用h5/js开发,页面体验更加受不了。Hybird的目的是实现H5和Naive两者之间的权衡

Hybird的实现方式

Hybrid是基于原生webview控件实现的,它主要要解决的问题有两个:
  • 原生端怎么调用JS代码
  • JS代码怎么调用原生端
这个问题进一步扩展,又细分为以下4个问题:
  • Q1: JS怎么调用Android代码
  • Q2: Android代码怎么调用JS
  • Q3: JS怎么调用IOS代码
  • Q4: IOS代码怎么调用JS

Q1: JS怎么调用Android代码

我们先讲下JS是怎么调Android代码的
主要有3种
  1. JSInterface
  2. JSBridge
  3. UrlRouter
1)JSInterface
从我们前端的角度看啊,是这样子滴~ :在Android中啊,有个叫做WebView的控件,这个控件的作用是可以在里面放一个网页然后运行它!我们前端就暂时把它理解成一个安卓APP里嵌入的微型浏览器吧,哈哈。然后呢,这个WebView控件对象还可以调用一个方法。
一个叫webView.addJavascriptInterface(接口对象,接口名)的方法,调用后,webView控件里面的HTML页面里的JS代码,就可以调用刚才addJavascriptInterface方法里的接口对象的原生方法了! 于是就这样,我们可以从JS间接调用原生Android代码,从此桥梁建立
例如,比如说我们下面定一个JSInterface的类,里面的showToast方法可以弹出一个原生的Toast
 
Android的原生代码
webView.addJavascriptInterface(new JsInterface(), "control”);
// …
public class JsInterface {
@JavascriptInterface
public void showToast(String toast) {
Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show();
log("show toast success");
} }
 
JS代码
// WebView中的JS代码,注意control就是上面addJavascriptInterface定义的命名空间
function showToast(toast) {
javascript:control.showToast(toast);
}
参考资料
 
2)JSbridge
从我们前端的角度看啊,其实是这样子滴~:就是在Android中啊,有这么一个WebChromeClient的组件,它就是上面讲到的WebView控件的一个子类。没错,它也可以在里面放一个网页去运行它,而且它牛啤的地方在于:你这个内部网页里的JS干的三件事可以被外层WebChromeClient给监听到:分别是前端的alert方法,confirm方法和prompt方法。只要你动了这三个方法,它们传递的数据就会被外部的WebChromeClient拦截和获取,这就为JS调Android的代码提供了一种方便的渠道。哎呀,三个方法这么多选哪个呢? 一般情况下,我们会选prompt方法,因为alert方法JS相对用的比较频繁,存在起冲突的可能
 
3)UrlRouter
这个东东还是和上面是一样的,Android的WebChromeClient控件这个类,它有个shouldOverrideUrlLoading这个方法,这个方法可以把控件内部网页的JS的Url请求给拦截了,当然了,你写在Url中的数据也同时被一并获取了。
总结:说白了JSInterface,JSBridge和UrlRouter主要的作用就是提供JS调原生代码的方式,搭一座桥梁
 
 

Q2: Android怎么调JS代码?

1)web view.loadUrl
有了上面的经验你肯定知道,这事还是webview这位老哥来做的,它可以通过调用webview.loadUrl方法加载一个HTML页面,这样HTML中的JS脚本不就被调用了吗?
webView.loadUrl(“...//my.html”);
2)webView.evaluateJavascript
上面的loadUrl有一个问题,它会导致页面刷新,而且通过加载文件的方式执行JS代码总不是我们认为最优雅的方式,我们可能期望的是执行一段指定的代码,而非一个文件,webView.evaluateJavascript就是做这件事情的,以下的代码可以执行一段JS代码
webView.evaluateJavascript(“JS代码”,Callback对象)
 
哦,对了,不好意思,上面讲的是Android的,下面讲下IOS怎么做

Q3: IOS代码怎么调用JS

1.可通过webview.stringByEvaluatingJavaScriptFromString方法调用JS方法,但前提是该JS方法在顶层Window对象上
webview.stringByEvaluatingJavaScriptFromString("方法名(参数)”)
 

Q4: JS怎么调用IOS代码

可通过 shouldStartLoadWithRequest方法进行拦截JS请求,从而感知JS的调用发起,并进行相应处理,以达到JS调用ios的效果
 
Hybrid也曾在移动端连接H5的童话世界中风靡一时,但由于对webview以及H5的过度依赖,导致它的体验性问题一直让人困扰,所以自从React-Native横空出世后,后者便蚕食了前者的半壁江山。
 

React-Native

RN的作用

  1. 跨平台:可以为IOS/Android,甚至Windows Phone开发原生应用
  2. 相对良好的UI体验,平衡开发成本和用户体验后相对合理的选择

RN的本质

  1. 不是WebView,和Cordova等Hybrid方案划清界限
  2. 不将JavaScript预编译为Native代码,和Xamarin等方案划清界限。Xammarin的方案是AOT的,运行前就编译为原生代码,RN则采用JIT+解释器的方案(IOS另当别论)
  3. RN是虚拟机类的方案,依靠运行时系统JavaScriptCore运行

RN的4个线程

  1. UI线程:也成为主线程,负责本机的Android/iOS的UI呈现,在android中它负责android测量/布局/绘制
  2. JS线程:执行JS/React代码,进行API调用,处理触摸事件等,对视图的更新被进行批处理,并在事件循环结束时发送给UI线程
  3. Shadow线程:处理虚拟DOM布局变更的线程
  4. 本机模块线程: 如android/ios系统自带的原生API

RN的3部分

  1. Native端(IOS/android)
  2. JavaScript端
  3. Bridge:上面介绍的多个线程之间相互通信,以及JS和Native端通信的方式的统称

线程协调过程示例

以下面一段RN代码的执行为例,它在JS线程中执行
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<View style={{width: 100, height: 100, backgroundColor: "red"}}></View>
</View>
  1. 注意原生端有自己的布局实现,所以上面的flex属性和CSS是没有任何关系的。
  2. 为了实现布局,同时又不阻塞JS线程,布局计算将转移到Shadow线程中进行。
  3. Shadow线程进行计算,并最终将计算结果得到的布局参数传递给主线程(UI线程),实现UI的构建

RN中的Bridge做了什么? && RN线程如何交互?

  • 异步:线程之间,例如JS线程和UI线程,以异步的方式进行通信,这样它们就不会互相阻塞了
  • 批处理: 以优化的方式, 把消息从一个线程传递到另外一个线程
  • 序列化: 两个线程不会操作或者共享同一块数据,它们之间会通过序列化和反序列化的方式交换消息

RN线程异步带来的某些问题 && 未来的解决方案

RN中的JS线程和UI线程之间是没有同步的方式的,这可能造成一些问题,但RN未来的Fabric也许能提供这一功能
 

RN的Web化:react-native-web

react-native-web 组件的内部,会把 React Native 的 API 映射成了浏览器支持的 API。将RN的代码转化成浏览器能支持的代码

RN-web和普通的React的区别?

RN-web尽量做到不侵入RN代码,不影响RN代码的逻辑,争取能够在基本不动RN项目代码的情况下,将其H5化,RN-web项目的基本逻辑还是RN,不是React

RN-WEB的作用

实现IOS/Android/Web的三端构建
 

参考文章

从Hybrid到React-Native: JS在移动端的南征北战史的更多相关文章

  1. 什么是 Native、Web App、Hybrid、React Native 和 Weex?(转载)

    什么是 Native.Web App.Hybrid.React Native 和 Weex?   来源:zwwill_木羽 segmentfault.com/a/1190000011154120 一句 ...

  2. Hybrid APP基础篇(二)->Native、Hybrid、React Native、Web App方案的分析比较

    说明 Native.Hybrid.React.Web App方案的分析比较 目录 前言 参考来源 前置技术要求 楔子 几种APP开发模式 概述 Native App Web App Hybrid Ap ...

  3. Native、Web App、Hybrid、React Native(简称RN)、Weex 间的异同点。

    App常用开发模式简介 此处App为应用application,并非我们通常讲的手机App. 常用的几种APP开发模式-脑图 Native App 传统的原生App开发模式,有iOS和aOS两大系统, ...

  4. 【REACT NATIVE 系列教程之十二】REACT NATIVE(JS/ES)与IOS(OBJECT-C)交互通信

    http://blog.csdn.net/xiaominghimi/article/details/51586492 一用到跨平台的引擎必然要有引擎与各平台原生进行交互通信的需要.那么Himi先讲解R ...

  5. 基于React Native的跨三端应用架构实践

    作者|陈子涵 编辑|覃云 “一次编写, 到处运行”(Write once, run anywhere ) 是很多前端团队孜孜以求的目标.实现这个目标,不但能以最快的速度,将应用推广到各个渠道,而且还能 ...

  6. Hybrid App 和 React Native 开发那点事

    简介:Hybrid App(混合模式移动应用)开发是指介于Web-app.Native-App这两者之间的一种开发模式,兼具「Native App 良好用户交互体验的优势」和「Web App 跨平台开 ...

  7. ReactJs和React Native的那些事

    介绍 1,React Js的目的 是为了使前端的V层更具组件化,能更好的复用,它能够使用简单的html标签创建更多的自定义组件标签,内部绑定事件,同时可以让你从操作dom中解脱出来,只需要操作数据就会 ...

  8. ReactJs和React Native的联系和差异

    1,React Js的目的 是为了使前端的V层更具组件化,能更好的复用,它能够使用简单的html标签创建更多的自定义组件标签,内部绑定事件,同时可以让你从操作dom中解脱出来,只需要操作数据就会改变相 ...

  9. React Native入门指南

    转载自:http://www.jianshu.com/p/b88944250b25 前言 React Native 诞生于 2015 年,名副其实的富二代,主要使命是为父出征,与 Apple 和 Go ...

随机推荐

  1. Sqlserver 查询把多行内容拼成一个字符串

    当使用:SELECT ','+Id FROM dbo.Test FOR XML PATH('')); //这样读取的数据虽然是1,2,3,4,但是仍然是xml格式,所以当数据超过2033时候,用sql ...

  2. win10下vc++6.0的安装问题

    由于最近需要在win10系统下用到vc++来编程(其实刚开始我是拒绝的,因为vc++各种坑),下面我就把安装vc++时遇到的问题记录下来,方便以后同样遇到这些问题的同学. 安装vc++6.0所需要东西 ...

  3. Container及其内部进程监控剖析

    目前市场上的虚拟化技术种类很多,例如moby(docker).LXC.RKT等等.在带来方便应用部署和资源充分利用的好处的同时,如何监控相应Container及其内部应用进程成为运维人员不可避免遇到的 ...

  4. ngxin安装之yum安装

    nginx部署至yum安装 1. 配置nginx所需的YUM源 [root@nginx]# cat /etc/yum.repos.d/yum.repo [nginx-stable] name=ngin ...

  5. SpringBoot 配置 AOP 打印日志

    在项目开发中,日志系统是必不可少的,用AOP在Web的请求做入参和出参的参数打印,同时对异常进行日志打印,避免重复的手写日志,完整案例见文末源码. 一.Spring AOP AOP(Aspect-Or ...

  6. 【Fishing Master HDU - 6709 】【贪心】

    题意分析 题意:题目给出n条鱼,以及捕一条鱼所用的时间k,并给出煮每一条鱼的时间,问抓完并煮完所有鱼的最短时间. 附题目链接 思路: 1.捕第一条鱼的时间是不可避免的,煮每条鱼的时间也是不可避免的,这 ...

  7. pycharm编辑器简单配置-- 持续更新完善

    目录 python解释器安装.多版本共存等 给pycharm编辑器选择python解释器版本 配置pip仓库地址 方式一:直接修改文件配置 方式二:pycharm配置 方式三:通过临时指定pip仓库地 ...

  8. C#中的变量祥解

    一.C#数据类型: A:值类型 值类型变量可以直接分配一个值,它是从System.ValueType派生而来,值类型直接包含数据,比如int,char,float,他们分别存储整型数据,字符,浮点数, ...

  9. Liunx学习总结(八)--服务

    什么是服务 服务是向外提供服务的进程,一般来说都会放在后台,既然要持续不断的提供外界随时发来的服务请求,服务进程就需要常驻在内存中,且不应该和终端有关,否则终端退出服务程序就退出了.另外,要能够接待外 ...

  10. Django之上传图片,分页,三级联动

    Django1.8.2中文文档:Django1.8.2中文文档 上传图片 配置上传文件保存目录 1)新建上传文件保存目录. 2)配置上传文件保存目录. 后台管理页面上传图片 1)设计模型类. 2)迁移 ...