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。

 

你可能感兴趣的:(PhoneGap)