非常早曾经写了一篇博客,总结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

cordova与ios native code交互的原理的更多相关文章

  1. Cordova - 与iOS原生代码交互1(通过JS调用Swift方法)

    在前面的文章中介绍的了如何使用Cordova进行跨平台应用的开发,使用Cordova的话基本上就不需要在写系统原生代码了,只要通过编写html页面和js方法即可. 但在有些特殊情况下,还是是需要htm ...

  2. 优秀开源代码解读之JS与iOS Native Code互调的优雅实现方案

    简介 本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge. 它优雅地实现了在使用UIWebView时JS与ios 的ObjC nativecode之间的互调,支持消息发 ...

  3. Hybrid----优秀开源代码解读之JS与iOS Native Code互调的优雅实现方案-备

    本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge. 它优雅地实现了在使用UIWebView时JS与ios 的ObjC nativecode之间的互调,支持消息发送.接 ...

  4. Cordova - 与iOS原生代码交互2(使用Swift开发Cordova的自定义插件)

    在前一篇文章中我介绍了如何通过 js 与原生代码进行交互(Cordova - 与iOS原生代码交互1(通过JS调用Swift方法)),当时是直接对Cordova生成的iOS工程项目进行编辑操作的(添加 ...

  5. webview的javascript与Native code交互

    http://my.oschina.net/u/1376187/blog/172296 项目中使用了webview显示网页,其中需要网页和native方法有交互,搜索到一篇文章,转发分享一下: === ...

  6. [Cordova] 无法编译Visual Studio项目里Plugin副本的Native Code

    [Cordova] 无法编译Visual Studio项目里Plugin副本的Native Code 问题情景 开发Cordova Plugin的时候,开发的流程应该是: 建立Cordova Plug ...

  7. [原]iOS中 Web 页面与 Native Code 的一种通信方式

    在 iOS 开发中,Web 页面与 Native Code 通信可以分为两个方面: 1.Native Code 调用 Web 页面的方法:主要是调用页面中的 Javascript 函数. 2.Web ...

  8. [转]iOS hybrid App 的实现原理及性能监测

    转自:http://www.cocoachina.com/ios/20151118/14270.html iOS hybrid App 的实现原理及性能监测 2015-11-18 11:39 编辑:  ...

  9. React Native 从入门到原理一

    React Native 从入门到原理一 React Native 是最近非常火的一个话题,介绍如何利用 React Native 进行开发的文章和书籍多如牛毛,但面向入门水平并介绍它工作原理的文章却 ...

随机推荐

  1. 51Nod 1048 整数分解为2的幂 V2

    题目链接 分析: $O(N)$和$O(NlogN)$的做法很简单就不写了...%了一发神奇的$O(log^3n*$高精度$)$的做法... 考虑我们只能用$2$的整次幂来划分$n$,所以我们从二进制的 ...

  2. 【Web前端】把图片嵌入到css样式表中(附小工具)

    适用场景: 本地通过stylish等插件自定义网站样式时 开通css自定义的空间但暂无图片上传途径时 ……   举例:     把视频页的缩略图边框改为下面这种        .main_list u ...

  3. Cocos2d-x中图字原理之深入分析

    http://cache.baiducontent.com/c?m=9d78d513d9921cfe05ac94281a16a632451294247c89df4f3992d15f9217465c02 ...

  4. (二十五)epoll深入理解续

    转自:http://blog.csdn.net/yusiguyuan/article/details/15027821 在Linux的网络编程中,很长的时间都在使用select来做事件触发.在linu ...

  5. unicode和utf8之间的关系

    ,字符编码是计算机技术的基石,想要熟练使用计算机,懂得一点字符编码的知识,还是很有必要的. 1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit ...

  6. Request的Body只能读取一次解决方法

    一.需要一个类继承HttpServletRequestWrapper,该类继承了ServletRequestWrapper并实现了HttpServletRequest, 因此它可作为request在F ...

  7. Codeforces 628 B.New Skateboard

      B. New Skateboard   time limit per test 1 second memory limit per test 256 megabytes input standar ...

  8. postgres表空间、模式、表和用户/角色之间的关系

    一. 角色(role)和用户(user)   1. role      postgres=# create role kanon password 'kanon';         #使用role创建 ...

  9. Topcoder 刷题之路_鶸的奋斗

    最近碰到的题不是水题就是坑题,实在没意思,听说神犇们都在Topcoder上刷SRM,于是我决定将SRM的DIV 1刷个遍.这里是目录 哎..好多转博客不注明出处的,这里给出本博客的出处:http:// ...

  10. 如何将netbeans生成的项目文件打包发布到其他的Tomcat服务器上?

    首先在netbeans中将项目文件生成.war文件,一个war包就是有特性格式的jar包,它是将一个Web程序的所有内容进行压缩得到,在netbeans中,在项目名称上右击鼠标->"清 ...