Cordova框架基本原理
最近在做混编项目,也是从项目里开始接触Cordova框架,网上很多帖子都总结的很好,我还是要总结一下,便于加深一下。
Cordova框架是一个可以让JS与原生代码(包括 Android 的 java,iOS 的 Objective-C 等)互相通信的一个库,并且提供了一系列的插件类,比如 JS 直接操作本地数据库的插件类。
要想明白它是如何互相通信的需要弄清楚下面三个问题:
1.JS怎么跟Objective-C通信
2.Objective-C怎么跟JS通信
3.JS请求Objective-C,Objective-C返回结果给JS,这样一来一往是怎么串起来的
JS与OC通信的关键代码在框架中Cordova.js文件中:
首先, HTML中需要加载Cordova.js
<script type="text/javascript" src="cordova.js"></script>
然后JS调用原生:
// successCallback : 成功的回调方法
// failCallback : 失败的回调方法
// server : 所要请求的服务名字,就是插件类的名字
// action : 所要请求的服务具体操作,其实就是Native 的方法名,字符串。
// actionArgs : 请求操作所带的参数,这是个数组。
cordova.exec(successCallback, failCallback, service, action, actionArgs);
cordova.js里定义的一个 var结构体,里面有一些方法以及其他变量,关于exec ,可以看 iOSExec这个js 方法,穿进来的这五个参数并不会直接传给原生,cordova.js会先做这样的处理:
- 会为每个请求生成一个叫 callbackId 的唯一标识:这个参数需传给 Objective-C 端,Objective-C 处理完后,会把 callbackId 连同处理结果一起返回给 JS 端
- 以 callbackId 为 key,{success:successCallback, fail:failCallback} 为 value,把这个键值对保存在 JS 端的字典里,successCallback 与 failCallback 这两个参数不需要传给 Objective-C 端,Objective-C 返回结果时带上 callbackId,JS 端就可以根据 callbackId 找到回调方法
- 每次 JS 请求,最后发到 Objective-C 的数据包括:callbackId, service, action, actionArgs 。
那么iOSExec又是怎么调用原生的呢:
实际上就是做一个假的url,在原生的webview中进行拦截。
原生代码拿到 callbackId、service、action 及 actionArgs 后,会做以下的处理:
- 根据 service 参数找到对应的插件类
- 根据 action 参数找到插件类中对应的处理方法,并把 actionArgs 作为处理方法请求参数的一部分传给处理方法
- 处理完成后,把处理结果及 callbackId 返回给 JS 端,JS 端收到后会根据 callbackId 找到回调方法,并把处理结果传给回调方法
关键代码:
- (void)sendPluginResult:(CDVPluginResult*)result callbackId:(NSString*)callbackId
{
CDV_EXEC_LOG(@"Exec(%@): Sending result. Status=%@", callbackId, result.status);
// This occurs when there is are no win/fail callbacks for the call.
if ([@"INVALID" isEqualToString : callbackId]) {
return;
}
int status = [result.status intValue];
BOOL keepCallback = [result.keepCallback boolValue];
NSString* argumentsAsJSON = [result argumentsAsJSON]; // 将请求的处理结果及 callbackId 通过调用 JS 方法返回给 JS 端
NSString* js = [NSString stringWithFormat:
@"cordova.require('cordova/exec').nativeCallback('%@',%d,%@,%d)",
callbackId, status, argumentsAsJSON, keepCallback]; [self evalJsHelper:js];
}
// 根据 callbackId 及是否成功标识,找到回调方法,并把处理结果传给回调方法
callbackFromNative: function(callbackId, success, status, args, keepCallback) {
var callback = cordova.callbacks[callbackId];
if (callback) {
if (success && status == cordova.callbackStatus.OK) {
callback.success && callback.success.apply(null, args);
} else if (!success) {
callback.fail && callback.fail.apply(null, args);
} // Clear callback if not expecting any more results
if (!keepCallback) {
delete cordova.callbacks[callbackId];
}
}
}
JS 端根据 callbackId 回调。
Cordova框架基本原理的更多相关文章
- PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码
PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码 看看新闻网>看引擎>开源产品 0人收藏此文章, 发表于8小时前(2013-09-06 00:39) ...
- 浅谈Cordova框架的一些理解
前言 因为工作原因,最近需要研究Cordova框架,看了其中的源码和实现方式,当场在看的时候马上能理解,但是事后再回去看相关源码时候却发现之前理解的内容又忘记了,又不得不重新开始看,所以总觉得需要记录 ...
- 在已有 Xcode 项目中 加入Cordova框架
转自:http://www.jianshu.com/p/656838ae92bc 我们知道,在UIKit中的UIWebView虽然已经提供了很多功能了,比如JavaScript和Objc之间的通信.但 ...
- 960CSS框架,之前有用过 了解下框架基本原理
http://blog.sina.com.cn/s/blog_8173443e010160b8.html CSS框架已经出现很长时间了,关于这些框架的用处也被我们讨论了很多遍了.有人说,CSS框架不够 ...
- .NET 框架基本原理透析⑴
.NET框架的核心便是通用语言运行时(CLR),顾名思义它是一个可被各种不同的编程语言所使用的运行时.CLR的很多特性可用于所有面向它的编程语言.比如,如果CLR用异常来报告错误,那么所有面向它的语言 ...
- 使用Cordova框架把Webapp封装成Hybrid App实践——Android篇
公司没有IOS和没有安卓开发人员,前端后端都是需要自己玩前几天技术经理说有一个需求要把webapp封装成Hybrid App,现已完成.记录一下从中遇到的问题和需要用到的开发环境的配置 将Webapp ...
- RPC框架基本原理(三):调用链路分析
本文主要阐述下RPC调用过程中的寻址,序列化,以及服务端调用问题. 寻址 随机寻址 从可用列表中,随机选择地址 一致性寻址 可用服务地址一致性hash管理:根据可服务的地址,构造treemap,计算c ...
- RPC框架基本原理(一):服务注册
什么是RPC框架 RPC整个过程涉及四类对象:客户端.客户端代理.服务端和服务端代理.RPC要求客户端和服务端之间约定好调用接口和传输格式(如JSON,Xml等),客户端在调用该接口时,由客户端的代理 ...
- cordova 框架下开发app推送
cordova提供官方的push pluging,使用的是Google的GCM消息推送服务,一些网络原因,国内GCM可能不怎么好用.所以选择国内的第三方插件. 可供选择的有百度云推送,腾讯云信鸽,极光 ...
随机推荐
- C++从string中删除所有的某个特定字符
C++中要从string中删除所有某个特定字符, 可用如下代码 str.erase(std::remove(str.begin(), str.end(), 'a'), str.end()); 其中, ...
- c#类,接口,结构,抽象类介绍 以及抽象和接口的比较
c#中的类是最常见的实际上就是对某种类型的对象定义变量和方法的原型. 结构是值类型,而类是引用类型. 1.与类不同,结构的实例化可以不使用 new 运算符.结构可以声明构造函数,但它们必须带参数. 2 ...
- C语言 extern学习1
没有头文件时,通过本文件内的函数声明来确定定义域,实现功能: //单文件测试 #include <stdio.h> /* 经测试,C语言环境下子函数默认是void型:所以可省略不写 为严谨 ...
- Java排序小算法(冒泡和选择)
package MyTest; import java.util.Scanner; public class BubbleSort { public void Init(int array[]) { ...
- 硅谷创业教父Paul Graham:如何获得创业idea
link:http://kb.cnblogs.com/page/165530/ 英文原文:How to Get Startup Ideas,翻译:Jason Zheng 要想获得创业 idea,请别试 ...
- struts2.5框架使用通配符指定方法(常见错误)
在学习struts框架时经常会使用到通配符调用方法,如下: <package name="shop" namespace="/" extends=&quo ...
- 阿里云服务器 发送邮箱 STMP 25端口 465端口问题 Javamail 25被禁用
我们传统使用的比较简单的是 STMP 25端口收发邮件 今天发现刚购买的阿里云服务器不能作为客户端通过STMP 25端口发送邮件 开始在网上有说发现是JDK1.8的原因,然后自己也把JDK1.8换到了 ...
- 精通gulp常用插件
本文主要展示的是gulp常用插件的使用方法和用途,通过对插件的熟练运用达到精通gulp.不定期更新.可以到github上面下载DEMO. github地址:lin-xin/gulp-plugins 匹 ...
- windows 2003装.net 4.0时提示 WIC windows Imaging Component
运行此安装程序之前,必须安装32位windows映像处理组件(WIC) WIC windows Imaging Component下载地址: http://download.microsoft.com ...
- 转:常用的iOS开源库和第三方组件
1.通过CocoaPods安装: