前提环境:
引用 Platform: android
Version: 3.4.0

(1)cordova.js/cordova_plugins.js文件

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

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

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

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

b)构建工具使用的是 Grunt,所以要先安装grunt-cli
引用 npm install -g grunt-cli

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

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

(3)cordova.js的整体结构
从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来自以下文件:
  • src\common\**.js
  • src\android\**.js
  • src\cordova.js

各文件输出形式:
引用 // file: <fileName>
<fileContents>

最终的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.jsdefine("cordova", function(require, exports, module) { /*...*/ }// file: src/android/android/nativeapiprovider.jsdefine("cordova/android/nativeapiprovider", function(require, exports, module) { /*...*/ }// file: src/android/android/promptbasednativeapi.jsdefine("cordova/android/promptbasednativeapi", function(require, exports, module) { /*...*/ }// file: src/common/argscheck.jsdefine("cordova/argscheck", function(require, exports, module) { /*...*/ }// file: src/common/base64.jsdefine("cordova/base64", function(require, exports, module) { /*...*/ }// file: src/common/builder.jsdefine("cordova/builder", function(require, exports, module) { /*...*/ }// file: src/common/channel.jsdefine("cordova/channel", function(require, exports, module) { /*...*/ }// file: src/android/exec.jsdefine("cordova/exec", function(require, exports, module) { /*...*/ }// file: src/common/exec/proxy.jsdefine("cordova/exec/proxy", function(require, exports, module) { /*...*/ }// file: src/common/init.jsdefine("cordova/init", function(require, exports, module) { /*...*/ }// file: src/common/modulemapper.jsdefine("cordova/modulemapper", function(require, exports, module) { /*...*/ }// file: src/android/platform.jsdefine("cordova/platform", function(require, exports, module) { /*...*/ }// file: src/android/plugin/android/app.jsdefine("cordova/plugin/android/app", function(require, exports, module) { /*...*/ }// file: src/common/pluginloader.jsdefine("cordova/pluginloader", function(require, exports, module) { /*...*/ }// file: src/common/urlutil.jsdefine("cordova/urlutil", function(require, exports, module) { /*...*/ }// file: src/common/utils.jsdefine("cordova/utils", function(require, exports, module) { /*...*/ }window.cordova = require('cordova');// file: src/scripts/bootstrap.jsrequire('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');


(4)cordova.js中个模块的说明

平台相关的:
  • src/android/android/nativeapiprovider.js JS->Native的具体交互形式
  • src/android/android/promptbasednativeapi.js 通过prompt()和Native交互(Android2.3 simulator的Bug)
  • src/android/exec.js ****执行JS->Native交互
  • src/android/platform.js ***bootstrap处理
  • src/android/plugin/android/app.js 清缓存、loadUrl、退出程序等

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

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

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


后续从四个方面继续分析cordova.js中一些核心代码:
(1)cordova.js模块系统require/define
  • src/scripts/require.js 自定义的模块系统

(2)cordova.js事件通道pub/sub
  • src/common/channel.js 发布/订阅模式的事件通道

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

(4)cordova.js本地交互JS<->Native
  • src/android/android/nativeapiprovider.js JS->Native的具体交互形式
  • src/android/android/promptbasednativeapi.js 通过prompt()和Native交互(Android2.3 simulator的Bug)
  • src/android/exec.js 执行JS->Native交互

剩下的代码就不分析了:
引用 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

下载带注释的cordova.js: 这里

参考:
http://www.cnblogs.com/linjisong/tag/PhoneGap/

更多相关文章

  1. Activity横竖屏切换时的UI处理
  2. android webview 加载进度和自定义404错误页面
  3. android 4中新增的日历处理相关API
  4. Cordova 3.x 源码分析(2) -- cordova.js概要
  5. android 4中新增的日历处理相关API
  6. Android(安卓)WebView的使用
  7. android应用去掉title bar 及全屏处理方法
  8. Android异步加载图像小结 (含线程池,缓存方法)
  9. android中SqLite query中用selectionArgs处理字符传值

随机推荐

  1. Android 获取文件的缩略图
  2. Android实现图片叠加效果的两种方法
  3. Android sqlite约束-视图-检查
  4. 老生常谈——Android冷启动优化
  5. Android培训班(35)
  6. Bitmap Error, cannot access an invalid
  7. Android 自定义 地图 室内
  8. Android(安卓)sdk manager 显示 “Done l
  9. Android 获取证书签名以及key hash散列值
  10. js判断ios、android