cordova与ios native code交互的原理

标签: cordova ios native | 发表时间:2014-08-06 18:00 | 作者:kyfxbl
出处:http://blog.csdn.net

很早以前写了一篇博客,总结cordova插件怎么调用到原生代码: cordova调用过程,不过写得太水,基本没有提到原理。最近加深了一点理解,重新补充说明一下

js调用native

下面是我们产品中的代码片段:

datePicker.show(options, function (date) {
    var month = date.getMonth() + 1;
    callback(null, date.getFullYear() + "-" + month + "-" + date.getDate());
});

cordova插件最终表现出来的都是js接口,并且调用者完全不需要知道自己在调用一个cordova插件

但是在任何cordova js方法内部,最后一定会调用cordova.exec函数:

cordova.exec(successCallback, errorCallback, "DatePicker", "show", []);

然后就进入了关键的cordova.exec函数,这是cordova框架的js端的最后一环,就是由它完成对ios native的调用

在exec函数里,首先会判断平台,可能是android,ios或者wp,其他平台本文省略,如果是ios平台,cordova会采用以下2种方式的一种,来与ios native code交互

通过iframe

cordova.exec往当前的html中插入一个不可见的iframe,从而向UIWebView请求加载一个特殊的URL,这个URL里当然就包含了要调用的native plugin的类名,方法名,参数,回调函数等信息

接下来,由于被请求加载URL,于是UIWebViewDelegate的这个方法被调用:

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

这里就进入了native侧,从request里就拿到了js端传过来的信息,然后调用到native plugin

通过XHR

另一种方式,cordova.exec里直接发起一个XHR请求,被native侧的NSURLProtocol拦截,于是调用到这个native方法:

+ (BOOL)canInitWithRequest:(NSURLRequest*)theRequest

也进入了native侧,然后以同样的方式调用到native plugin

在2种方式中,cordova会优先选择XHR方式,只有当XHR方式不可用时,才会使用iframe的方式。不过无论怎么样,这2种方法都为从js到native打开了一条通道,剩下的就是传递参数和路由的问题了

native调用js

另一条通道就简单的多,因为iOS提供了原生支持,所以不需要想特别的办法。即通过UIWebView的这个方法:

- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;

看一下cordova框架native侧的代码,我去掉了注释和无关代码:

- (void)evalJsHelper:(NSString*)js
{
    if (![NSThread isMainThread] || !_commandQueue.currentlyExecuting) {
        [self performSelectorOnMainThread:@selector(evalJsHelper2:) withObject:js waitUntilDone:NO];
    } else {
        [self evalJsHelper2:js];
    }
}

- (void)evalJsHelper2:(NSString*)js
{
    NSString* commandsJSON = [_viewController.webView stringByEvaluatingJavaScriptFromString:js];
}

可以看到,正是通过UIWebView提供的这个方法完成的,但是,一定执行在main thread

同步和异步的问题

从上面的分析可以发现,从js调用native,2种方式都必定是异步的。而从native回到js,却是一个同步的方法,而且是跑在主线程里

调用cordova插件的代码,对返回值的处理一定要放在回调函数里,因为结果是异步返回的。同时,回调函数的执行时间不能太长,否则会阻塞native主线程

参考

本文参考了以下2篇文章,都写得很好:

iOS版PhoneGap原理分析

浅析Cordova for iOS




作者:kyfxbl 发表于2014-8-6 18:00:57 原文链接
阅读:0 评论:0 查看评论

相关 [cordova ios native] 推荐:

cordova与ios native code交互的原理

- - CSDN博客推荐文章
很早以前写了一篇博客,总结cordova插件怎么调用到原生代码: cordova调用过程,不过写得太水,基本没有提到原理. 最近加深了一点理解,重新补充说明一下. 下面是我们产品中的代码片段:. cordova插件最终表现出来的都是js接口,并且调用者完全不需要知道自己在调用一个cordova插件.

使用 Dojo Mobile 为 iOS 智能终端开发 Native-like Web 应用

- jiaosq - IBM developerWorks 中国 : 文档库
随着 iOS 智能终端的流行,基于 iOS 开发 Native-like Web 应用变得越来越流行. 本文着重介绍基于 Dojo Mobile 开发 Native-like Web 应用的方法,并分享一些开发经验和技巧.

谈谈 React Native

- - 唐巧的技术博客
几天前,Facebook 在 React.js Conf 2015 大会上推出了 React Native( 视频链接). 我发了一条微博( 地址),结果引来了 100 多次转发. 为什么 React Native 会引来如此多的关注呢. 我在这里谈谈我对 React Native 的理解. 一个新框架的出现总是为了解决现有的一些问题,那么对于现在的移动开发者来说,到底有哪些问题 React Native 能涉及呢.

构建一个完整的Cordova应用

- - SegmentFault 最新的文章
本文承接上篇《创建Cordova插件》,通过实现一个简单的应用作为这个Cordova初级系列的结束. 前边对Cordova编程已经讲了不少了,还没有拿真实应用为例完整的演练一遍构建过程. 这里将用一个完整的应用为例从头到尾一步步的演示如何创建和测试应用. 把所有的API集中在一个例子中展示是一个好办法.

Chrome 14 beta启用Native Client

- tinda - Solidot
Google发布了Chrome 14 beta,默认启用Native Client(NaCl),它最早在上半年发布的Chrome 10 beta整合了NaCl,但并未激活. Google在2008年首次推出了试验项目NaCl,让开发者可以编译C/C++代码为不针对特定平台的二进制文件,在浏览器整合的运行时中执行,利用沙盒技术避开安全缺陷.

剑走偏锋的 Native Client

- - 谷奥——探寻谷歌的奥秘
感谢读者  liuyanghejerry 的投稿. 不知不觉,Google已经正式推出其Native Client (NaCl)过去约7个月之久. 而目前国内似乎还没有多少关于NaCl的资料,所以在这里面向Web开发者做一下简单的介绍,希望能够起到一个抛砖引玉的效果. 本文的所有代码均来自于 https://developers.google.com/native-client/devguide/tutorial,如果您对其中的任何技术细节存在疑问,请以原文为准.

基于Apache Cordova开发移动平台上的Chrome Apps

- - Chrome迷
不好意思,迟到的新闻,同时给大家拜个晚年,祝大家马年吉祥马上有钱. 据去年9月份的消息,Chrome Apps将可以像原生应用一样在各终端设备上离线运行,目前已经做到兼容了所有的桌面平台. 而现在通过一个基于 Apache Cordova的开发者预览版工具包,Chrome Apps已经实现可以直接在Android和iOS设备上运行了.

Android Native 代码开发学习笔记

- iDesperadO - WindStorm
本文提供排版更佳的PDF版本下载. JNI,全称Java Native Interface,是用于让运行在JVM中的Java代码和运行在JVM外的Native代码(主要是C或者C++)沟通的桥梁. 代码编写者即可以使用JNI从Java的程序中调用Native代码,又可以从Native程序中调用Java代码.

使用 Java Native Interface 的最佳实践

- - 博客 - 伯乐在线
简介: Java™ 本机接口(Java Native Interface,JNI)是一个标准的 Java API,它支持将 Java 代码与使用其他 编程语言编写的代码相集成. 如果您希望利用已有的代码资源,那么可以使用 JNI 作为您工具包中的关键组件 —— 比如在面向服务架构(SOA)和基于云的系统中.

Web App和Native App 谁将是未来

- - 互联网旁观者
未来是Web App的天下,还是Native App的天下. 作为设计师,我们是应该努力把客户端的体验提升到最优,还是在网页应用层面上做更多的设计. 那么,我们首先应该立体的认识一下Web App和Native App. Web 无需安装,对设备碎片化的适应能力优于App,它只需要通过XHTML、CSS和JavaScript就可以在任意移动浏览器中执行.