念奴娇 赤壁怀古
     [北宋]苏轼
大江东去,浪淘尽,千古风流人物。
故垒西边,人道是,三国周郎赤壁。
乱石穿空,惊涛拍岸,卷起千堆雪。
江山如画,一时多少豪杰。

遥想公瑾当年,小乔初嫁了,雄姿英发。
羽扇纶巾,谈笑间,樯橹灰飞烟灭。
故国神游,多情应笑我,早生华发。
人生如梦,一樽还酹江月。

PhoneGap源码分析11——cordova/common

  在引导程序中,导入cordova/builder之后,便是导入cordova/common,这是所有平台公共的模块部分,在cordova/common构造函数中,通过返回一个配置对象,非常精巧的将公共模块组织起来,并通过引导程序中的builder.build(base.objects).intoButDontClobber(window)将这些模块在window全局中构建。

  我们看看这个配置对象:

define("cordova/common", function(require, exports, module) {
module.exports = {
    objects: {
        cordova: {
            path: 'cordova',
            children: {
            }
        },
        Cordova: {
            children: {
            }
        },
        PhoneGap:{
            children: {
            }
        },
        navigator: {
            children: {
            }
        },
        Acceleration: {
            path: 'cordova/plugin/Acceleration'
        },
        // 省略了其它一些配置
        resolveLocalFileSystemURI:{
            path: 'cordova/plugin/resolveLocalFileSystemURI'
        }
    }
};

1、从整体上来说,配置对象是一个对象字面量,是一些属性的集合,而这些属性,会通过builder模块导入至window对象。
2、考察配置对象内部的属性对象,发现有三种情况:属性对象只有一个path子属性、属性对象只有子属性children、属性对象同时有path和children两个子属性。再回看一下builder中include代码:

(1)含有path,首先会使用require(path)导入path指定的模块,作为导入window全局的一个中间备选对象(具体导入方式和调用builder中返回方法相关)。如果没有path,则中间备选对象是一个没有属性的空对象{}。

(2)含有children的,我们可以看到,children本身也是一个和全局配置对象结构相同的配置对象,然后在builder的include方法中,将中间备选对象作为父对象,递归导入children中的模块。不含children的,则导入结束。

3、在配置对象中,有一个公共的cordova/exec我们还没有分析,这是PhoneGap库和Android的通讯方法,从代码中可以看到,在PhoneGap中只是简单的调用了prompt这个函数,在Android本地会解析传入的参数并调用相应的命令。来看看它的源码:

define("cordova/exec", function(require, exports, module) {
 /**
  * 执行cordova命令
  * 同步:返回一个JSON字符串;异步:返回空字符串"",这个时候可以根据处理结果调用回调函数
  * 参数:(1)success:命令执行成功回调函数
  *       (2)fail:命令执行失败回调函数
  *       (3)service:使用的服务名称
  *       (4)action:在cordova中运行的命令
  *       (5)args:0或多个参数组成的数组
  */
var cordova = require('cordova');

module.exports = function(success, fail, service, action, args) {
  try {
    var callbackId = service + cordova.callbackId++;//内部回调id
    if (success || fail) {//至少传入了其中一个
        cordova.callbacks[callbackId] = {success:success, fail:fail};
    }

  //将参数转化为JSON字符串去执行
var r = prompt(JSON.stringify(args), "gap:"+JSON.stringify([service, action, callbackId, true])); if (r.length > 0) { var v = JSON.parse(r);//将返回结果解析成对象 if (v.status === cordova.callbackStatus.OK) { if (success) {//调用成功回调函数 try { success(v.message); } catch (e) { console.log("Error in success callback: " + callbackId + " = " + e); } // 清除回调函数 if (!v.keepCallback) { delete cordova.callbacks[callbackId]; } } return v.message; } else if (v.status === cordova.callbackStatus.NO_RESULT) { // 清除回调函数 if (!v.keepCallback) { delete cordova.callbacks[callbackId]; } } else {// 错误 console.log("Error: Status="+v.status+" Message="+v.message); // 调用失败回调函数 if (fail) { try { fail(v.message); } catch (e1) { console.log("Error in error callback: "+callbackId+" = "+e1); } //清除回调函数 if (!v.keepCallback) { delete cordova.callbacks[callbackId]; } } return null; } } } catch (e2) { console.log("Error: "+e2); } }; });

4、至于导入的具体内容,则是PhoneGap库针对移动平台开发的公共模块了,比如访问摄像机(Camera)、通讯录(Contact)等,可以参考源代码以及官方API。

 

posted @ 2012-08-15 15:55  linjisong  阅读(1204)  评论(1编辑  收藏  举报