Cordova 3.x 源码分析(2) -- cordova.js概要

前提环境:
[quote]Platform: android
Version: 3.4.0[/quote]

[b](1)cordova.js/cordova_plugins.js文件[/b]

cordova.js在创建Android工程的时候,是从cordova的lib目录下Copy到platforms\android\assets\www\cordova.js的。同时备份到platforms\android\platform_www\cordova.js
[quote]C:\Documents and Settings\RenSanNing\.cordova\lib\android\cordova\3.4.0\framework\assets\www\cordova.js[/quote]

而platforms\android\assets\www\cordova_plugins.js是根据plugins文件夹的内容生成的。

[b](2)自己亲手生成cordova.js[/b]
Cordova是OSS的,所以可以通过源代码来生成cordova.js

a)下载源码
目前稳定版是3.4.0,master是3.5.0-dev。
从[url=https://github.com/apache/cordova-js/tree/3.4.x]https://github.com/apache/cordova-js/tree/3.4.x[/url]下载cordova-js-3.4.x.zip解压到E:\cordova-js-3.4.x

b)构建工具使用的是[url=http://gruntjs.com/]Grunt[/url],所以要先安装grunt-cli
[quote]npm install -g grunt-cli[/quote]

c)手动生成
[quote]cd E:\cordova-js-3.4.x
npm install --安装package.json中devDependencies定义的依赖包
grunt --运行 grunt[/quote]

d)执行后多了2个文件夹
node_modules 依赖包
pkg
cordova.android.js
cordova.ios.js
...
其中cordova.android.js就是我们Android工程要用到的cordova.js了。

[b](3)cordova.js的整体结构[/b]
从E:\cordova-js-3.4.x\tasks\lib\bundle.js可以看出cordova.js的整体结构是:
// Platform:  <platform>
// <commitId>
/* <license> */
;(function() {
var CORDOVA_JS_BUILD_LABEL = '<commitId>';
// src\scripts\require.js文件内容
// 各Module文件内容
window.cordova = require('cordova');
// src\scripts\bootstrap.js文件内容
})();


其中Module来自以下文件:
[list][*]src\common\**.js
[*]src\android\**.js
[*]src\cordova.js[/list]

各文件输出形式:
[quote]// file: <fileName>
<fileContents>[/quote]

最终的cordova.js:
// Platform: android
// 3.4.0
/*
License 省略
*/
;(function() {
var CORDOVA_JS_BUILD_LABEL = '3.4.0';
// file: src/scripts/require.js
//...
// file: src/cordova.js
define("cordova", function(require, exports, module) { /*...*/ }
// file: src/android/android/nativeapiprovider.js
define("cordova/android/nativeapiprovider", function(require, exports, module) { /*...*/ }
// file: src/android/android/promptbasednativeapi.js
define("cordova/android/promptbasednativeapi", function(require, exports, module) { /*...*/ }
// file: src/common/argscheck.js
define("cordova/argscheck", function(require, exports, module) { /*...*/ }
// file: src/common/base64.js
define("cordova/base64", function(require, exports, module) { /*...*/ }
// file: src/common/builder.js
define("cordova/builder", function(require, exports, module) { /*...*/ }
// file: src/common/channel.js
define("cordova/channel", function(require, exports, module) { /*...*/ }
// file: src/android/exec.js
define("cordova/exec", function(require, exports, module) { /*...*/ }
// file: src/common/exec/proxy.js
define("cordova/exec/proxy", function(require, exports, module) { /*...*/ }
// file: src/common/init.js
define("cordova/init", function(require, exports, module) { /*...*/ }
// file: src/common/modulemapper.js
define("cordova/modulemapper", function(require, exports, module) { /*...*/ }
// file: src/android/platform.js
define("cordova/platform", function(require, exports, module) { /*...*/ }
// file: src/android/plugin/android/app.js
define("cordova/plugin/android/app", function(require, exports, module) { /*...*/ }
// file: src/common/pluginloader.js
define("cordova/pluginloader", function(require, exports, module) { /*...*/ }
// file: src/common/urlutil.js
define("cordova/urlutil", function(require, exports, module) { /*...*/ }
// file: src/common/utils.js
define("cordova/utils", function(require, exports, module) { /*...*/ }
window.cordova = require('cordova');
// file: src/scripts/bootstrap.js
require('cordova/init');
})();


***define()的顺序是在Grunt的时候简单的按模块ID名升序排的,先后无所谓。
***define只是注册模块,不会调用其factory。
***在index.html通过<script type="text/javascript" src="cordova.js"></script>引入cordova.js后:

// 加载cordova模块,赋给window.cordova
// require()第一次被调用,就开始调用其factory。
// factory中又包含了其他的require(),就形成了嵌套,直到最后所有module的factory被执行完。
window.cordova = require('cordova');
// 加载Plugin代码等初期化处理
require('cordova/init');


[b](4)cordova.js中个模块的说明[/b]

平台相关的:
[list][*]src/android/android/nativeapiprovider.js [color=blue]JS->Native的具体交互形式[/color]
[*]src/android/android/promptbasednativeapi.js [color=blue]通过prompt()和Native交互([url=https://code.google.com/p/android/issues/detail?id=12987]Android2.3 simulator的Bug[/url])[/color]
[*]src/android/exec.js [color=blue]****执行JS->Native交互[/color]
[*]src/android/platform.js [color=blue]***bootstrap处理[/color]
[*]src/android/plugin/android/app.js [color=blue]清缓存、loadUrl、退出程序等[/color][/list]

通用的:
[list][*]src/common/argscheck.js [color=blue]用于plugin中校验参数,比如argscheck.checkArgs('fFO', 'Camera.getPicture', arguments); 参数应该是2个函数1个对象[/color]
[*]src/common/base64.js [color=blue]JS->Native交互时对ArrayBuffer进行uint8ToBase64(WebSockets二进制流)[/color]
[*]src/common/builder.js [color=blue]对象属性操作,比如把一个对象的属性Merge到另外一个对象[/color]
[*]src/common/channel.js [color=blue]****控制事件调用[/color]
[*]src/common/exec/proxy.js [color=blue]用于Plugin中往已经有的模块上添加方法[/color]
[*]src/common/init.js [color=blue]****初期处理[/color]
[*]src/common/modulemapper.js [color=blue]***把定义的模块clobber到一个对象,在初期化的时候会赋给window[/color]
[*]src/common/pluginloader.js [color=blue]***加载所有cordova_plugins.js中定义的模块,执行完成后会触发onPluginsReady[/color]
[*]src/common/urlutil.js [color=blue]获取绝对URL,InAppBrowser中会用到[/color]
[*]src/common/utils.js [color=blue]工具类[/color][/list]

核心:
[list][*]src/cordova.js [color=blue]****事件的处理和回调,外部访问cordova.js的入口[/color]
[*]src/scripts/require.js [color=blue]*****模块化系统[/color]
[*]src/scripts/bootstrap.js [color=blue]启动处理(只调用了初期处理require('cordova/init');),注意和platform的bootstrap处理不一样[/color][/list]

[b](5)cordova_plugins.js的整体结构[/b]
Cordova从3.0版本开始不再在cordova.js中包含各plugin的代码,而是采用plugman通过CLI生成cordova_plugins.js然后动态加载需要的plugin。3.0之前的代码结构可以参考:[url=https://github.com/apache/cordova-js/tree/2.8.x]https://github.com/apache/cordova-js/tree/2.8.x[/url] lib-<platform>/plugin/<platform>

cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [
{
"file": "plugins/org.apache.cordova.vibration/www/vibration.js",
"id": "org.apache.cordova.vibration.notification",
"merges": [
"navigator.notification"
]
},
//.......
];
module.exports.metadata =
// TOP OF METADATA
{
"org.apache.cordova.vibration": "0.3.7",
// ....
}
// BOTTOM OF METADATA
});


其实也是define了一个ID为“cordova/plugin_list”的模块,在初期化的时候动态加载到head里的。Cordova提供的Native API的js也是一样的,可以启动浏览器调试看HTML的Head部分:
[img]http://dl2.iteye.com/upload/attachment/0096/3092/856332dd-c043-3806-950d-28c066c5faac.png[/img]

[color=blue][size=medium][b]后续从四个方面继续分析cordova.js中一些核心代码:[/b][/size][/color]
[url=http://rensanning.iteye.com/blog/2047324](1)cordova.js模块系统require/define[/url]
[list][*] src/scripts/require.js 自定义的模块系统[/list]

[url=http://rensanning.iteye.com/blog/2051889](2)cordova.js事件通道pub/sub[/url]
[list][*] src/common/channel.js 发布/订阅模式的事件通道[/list]

[url=http://rensanning.iteye.com/blog/2052142](3)cordova.js导入、初始化、启动、加载插件[/url]
[list][*] src/cordova.js 事件的处理和回调,外部访问cordova.js的入口
[*] src/common/init.js 初始化处理
[*] src/android/platform.js 平台启动处理
[*] src/common/pluginloader.js 加载所有cordova_plugins.js中定义的模块,执行完成后会触发onPluginsReady [/list]

[url=http://rensanning.iteye.com/blog/2054049](4)cordova.js本地交互JS<->Native[/url]
[list][*] src/android/android/nativeapiprovider.js JS->Native的具体交互形式
[*] src/android/android/promptbasednativeapi.js 通过prompt()和Native交互(Android2.3 simulator的Bug)
[*] src/android/exec.js 执行JS->Native交互[/list]

剩下的代码就不分析了:
[quote]src/android/plugin/android/app.js
src/common/argscheck.js
src/common/base64.js
src/common/builder.js
src/common/exec/proxy.js
src/common/modulemapper.js
src/common/urlutil.js
src/common/utils.js[/quote]

下载带注释的cordova.js:[url=http://dl.iteye.com/topics/download/d0f0b293-89c6-3931-8139-4bcaebe5e52f]这里[/url]

参考:
[url=http://www.cnblogs.com/linjisong/tag/PhoneGap/]http://www.cnblogs.com/linjisong/tag/PhoneGap/[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值