9 (phonegap源碼分析)代碼附錄

index.html 源碼 
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<script  type="text/javascript"  charset="utf-8"  src="js/myphonegap.js"></script>
</head>

<body>
<p>PHONEGAP SIMULATE !</p>

</body>
</html>


MainActivity.java 源碼


package com.example.mobilephonebills;

import com.example.telephonefare.R;
import com.example.telephonefare.R.layout;
import com.example.telephonefare.R.menu;
 
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;

public class ChartActivity extends Activity {
	WebView mWebView = null;
	LinearLayout mMenuItem1,mMenuItem2,mMenuItem3;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_chart);
		
		prepareView();
	}

	private void prepareView(){	 
		mMenuItem1 = (LinearLayout)findViewById(R.id.home_menu_bt1);
		mMenuItem2 = (LinearLayout)findViewById(R.id.home_menu_bt2);
		mMenuItem3 = (LinearLayout)findViewById(R.id.home_menu_bt3);
		 
		OnClickListener listener2= new OnClickListener(){
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				switch(v.getId()){
				case R.id.home_menu_bt1:
					
					break;
				case R.id.home_menu_bt2:
					Intent intent3 = new Intent(ChartActivity.this,ChartActivity.class);
    				ChartActivity.this.startActivity(intent3);
					break;
				case R.id.home_menu_bt3:
    				
					break;
				default:
						break;
				}
			}
		
		};	
		mMenuItem1.setOnClickListener(listener2);
		mMenuItem2.setOnClickListener(listener2);
		mMenuItem3.setOnClickListener(listener2);
		
		mWebView = (WebView)findViewById(R.id.charts_webView);
		mWebView.setBackgroundColor(0);
        mWebView.setWebViewClient(new MyWebViewClient());
        mWebView.setBackgroundColor(0);
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
        
        mWebView.loadUrl("file:///android_asset/www/chart.html");
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.chart, menu);
		return true;
	}

	 private class MyWebViewClient extends WebViewClient{
		 // 在WebView中而不是默認瀏覽器中顯示頁面 
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // TODO Auto-generated method stub
        	 if (Uri.parse(url).getHost().equals("file:///android_asset/www/chart.html")) {
                 // This is my web site, so do not override; let my WebView load the page
                 return false;
             }
        	view.loadUrl(url);
            return true;
        }
        
    }
	 
}

myphonegap.js 源碼


;(function(){
  var  require,//myphonegap內部的工具函數,用來導入相關的模塊
        define;//在myphonegap註冊相關的模塊

  //通過一個立即調用的匿名函數,來給require和define賦上實際的函數
  (function(){
		var modules={};   // 模塊數組,添加模塊類似給這個對象添加了屬性,模塊名爲屬性名,模塊對象爲屬性值,或者說是鍵值對
				
		build = function(module){        //根據模塊對象構造模塊導出對象,模塊導出對象存儲在modules這個對象數組內
			var factory = module.factory;
			module.exports = {};           //給當前模塊加入了一個exports屬性
			delete module.factory;		   //刪除了module的屬性
			factory(require,module.exports,module);     //構建導出模塊,module.exports是傳出參數(實參,引用傳遞)
			return module.exports;
		}
		
		require = function(id){            //根據模塊名稱/id請求模塊對象,如果是第一次請求,就構建對象
			if(!modules[id]){
				throw "module " + id + " not found!";
			}
			return modules[id].factory?build(modules[id]):modules[id].exports;
		}
	
		define = function(id,factory){		 //定義模塊,模塊名稱、構建模塊對象的工廠方法。
			if(modules[id]){                  
				throw "module " + id + " is exist!";
			}
			modules[id] = {					//定義模塊對象,左邊的值爲屬性名,右邊的值爲傳入的參數 
				id:id,						
				factory:factory
			};
		}
  })();

  //註冊myphonegap模塊
  define("myphonegap", function(require, exports, module){
		console.info("create myphonegap module");
		
		var channel = require('myphonegap/channel');

		document.addEventListener('DOMContentLoaded', function() {
			channel.onDOMContentLoaded.fire();
		}, false);
		if (document.readyState == 'complete' || document.readyState == 'interactive') {
			channel.onDOMContentLoaded.fire();
		}

		var m_document_addEventListener = document.addEventListener;
		var m_document_removeEventListener = document.removeEventListener;
		var m_window_addEventListener = window.addEventListener;
		var m_window_removeEventListener = window.removeEventListener;

		var documentEventHandlers = {},
			windowEventHandlers = {};

		document.addEventListener = function(evt, handler, capture) {
			var e = evt.toLowerCase();
			if (typeof documentEventHandlers[e] != 'undefined') {
				documentEventHandlers[e].subscribe(handler);
			} else {
				m_document_addEventListener.call(document, evt, handler, capture);
			}
		};

		window.addEventListener = function(evt, handler, capture) {
			var e = evt.toLowerCase();
			if (typeof windowEventHandlers[e] != 'undefined') {
				windowEventHandlers[e].subscribe(handler);
			} else {
				m_window_addEventListener.call(window, evt, handler, capture);
			}
		};

		document.removeEventListener = function(evt, handler, capture) {
			var e = evt.toLowerCase();
			// If unsubscribing from an event that is handled by a plugin
			if (typeof documentEventHandlers[e] != "undefined") {
				documentEventHandlers[e].unsubscribe(handler);
			} else {
				m_document_removeEventListener.call(document, evt, handler, capture);
			}
		};

		window.removeEventListener = function(evt, handler, capture) {
			var e = evt.toLowerCase();
			// If unsubscribing from an event that is handled by a plugin
			if (typeof windowEventHandlers[e] != "undefined") {
				windowEventHandlers[e].unsubscribe(handler);
			} else {
				m_window_removeEventListener.call(window, evt, handler, capture);
			}
		};

		function createEvent(type, data) {
			var event = document.createEvent('Events');
			event.initEvent(type, false, false);
			if (data) {
				for (var i in data) {
					if (data.hasOwnProperty(i)) {
						event[i] = data[i];
					}
				}
			}
			return event;
		}

		if(typeof window.console === "undefined") {
			window.console = {
				log:function(){}
			};
		}

		var myphonegap = {
			define:define,
			require:require,
			/** 
			 *在document和window上添加自定義的事件監聽器方法
			 * Methods to add/remove your own addEventListener hijacking on document + window.
			 */
			addWindowEventHandler:function(event) {
				return (windowEventHandlers[event] = channel.create(event));
			},
			addStickyDocumentEventHandler:function(event) {
				return (documentEventHandlers[event] = channel.createSticky(event));
			},
			addDocumentEventHandler:function(event) {
				return (documentEventHandlers[event] = channel.create(event));
			},
			removeWindowEventHandler:function(event) {
				delete windowEventHandlers[event];
			},
			removeDocumentEventHandler:function(event) {
				delete documentEventHandlers[event];
			},
			/**
			 * 以對象形式返回DOM中原來定義的事件偵聽函數
			 * @return object
			 */
			getOriginalHandlers: function() {
				return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
				'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
			},
			/**
			 *從本地代碼觸發事件
			 */
			fireDocumentEvent: function(type, data, bNoDetach) {
				var evt = createEvent(type, data);
				if (typeof documentEventHandlers[type] != 'undefined') {
					if( bNoDetach ) {
					  documentEventHandlers[type].fire(evt);
					}
					else {
					  setTimeout(function() {
						  documentEventHandlers[type].fire(evt);
					  }, 0);
					}
				} else {
					document.dispatchEvent(evt);
				}
			},
			fireWindowEvent: function(type, data) {
				var evt = createEvent(type,data);
				if (typeof windowEventHandlers[type] != 'undefined') {
					setTimeout(function() {
						windowEventHandlers[type].fire(evt);
					}, 0);
				} else {
					window.dispatchEvent(evt);
				}
			},

			 /**
			 * 插件回調機制
             * 回調ID採用隨機數避免加載刷新後發生衝突,這樣避免新的回調函數取得和舊回調函數同樣的ID
			 */
			callbackId: Math.floor(Math.random() * 2000000000),
			callbacks:  {},
			callbackStatus: {
				NO_RESULT: 0,
				OK: 1,
				CLASS_NOT_FOUND_EXCEPTION: 2,
				ILLEGAL_ACCESS_EXCEPTION: 3,
				INSTANTIATION_EXCEPTION: 4,
				MALFORMED_URL_EXCEPTION: 5,
				IO_EXCEPTION: 6,
				INVALID_ACTION: 7,
				JSON_EXCEPTION: 8,
				ERROR: 9
			},

			/**
			 * 本地方法返回成功時調用該函數
			 */
			callbackSuccess: function(callbackId, args) {
				try {
					myphonegap.callbackFromNative(callbackId, true, args.status, args.message, args.keepCallback);
				} catch (e) {
					console.log("Error in error callback: " + callbackId + " = "+e);
				}
			},

			/**
			 * 本地方法返回失敗時調用該函數
			 */
			callbackError: function(callbackId, args) {
				try {
					myphonegap.callbackFromNative(callbackId, false, args.status, args.message, args.keepCallback);
				} catch (e) {
					console.log("Error in error callback: " + callbackId + " = "+e);
				}
			},

			/**
			 * 從本地動作返回一個結果時調用該函數
			 */
			callbackFromNative: function(callbackId, success, status, message, keepCallback) {
				var callback = myphonegap.callbacks[callbackId];
				if (callback) {
					if (success && status == myphonegap.callbackStatus.OK) {
						callback.success && callback.success(message);
					} else if (!success) {
						callback.fail && callback.fail(message);
					}

					// Clear callback if not expecting any more results
					if (!keepCallback) {
						delete myphonegap.callbacks[callbackId];
					}
				}
			},
			addConstructor: function(func) {
				channel.onMyphonegapReady.subscribe(function() {
					try {
						func();
					} catch(e) {
						console.log("Failed to run constructor: " + e);
					}
				});
			},
			Hello:function(name){
				console.info("hello, "+name +" !");
			}
		};
		
		module.exports = myphonegap;
  });


  //註冊myphonegap/builder模塊
 
	define("myphonegap/builder", function(require, exports, module) {

		var utils = require('myphonegap/utils');

		function each(objects, func, context) {
			for (var prop in objects) {
				if (objects.hasOwnProperty(prop)) {
					//console.info(prop);
					func.apply(context, [objects[prop], prop]);
				}
			}
		}


		function clobber(obj, key, value) {
			obj[key] = value;
			// Getters can only be overridden by getters.
			if (obj[key] !== value) {
				utils.defineGetter(obj, key, function() {
					return value;
				});
			}
		}

		function assignOrWrapInDeprecateGetter(obj, key, value, message) {
			if (message) {
				utils.defineGetter(obj, key, function() {
					console.log(message);
					delete obj[key];
					clobber(obj, key, value);
					return value;
				});
			} else {
				clobber(obj, key, value);
			}
		}

		function include(parent, objects, clobber, merge) {
			each(objects, function (obj, key) {
				try {
				  var result = obj.path ? require(obj.path) : {};

				  if (clobber) {
					  // Clobber if it doesn't exist.
					  if (typeof parent[key] === 'undefined') {
						  assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
					  } else if (typeof obj.path !== 'undefined') {
						  // If merging, merge properties onto parent, otherwise, clobber.
						  if (merge) {
							  recursiveMerge(parent[key], result);
						  } else {
							  assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
						  }
					  }
					  result = parent[key];
				  } else {
					// Overwrite if not currently defined.
					if (typeof parent[key] == 'undefined') {
					  assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
					} else {
					  // Set result to what already exists, so we can build children into it if they exist.
					  result = parent[key];
					}
				  }

				  if (obj.children) {
					include(result, obj.children, clobber, merge);
				  }
				} catch(e) {
				  utils.alert('Exception building myphonegap JS globals: ' + e + ' for key "' + key + '"');
				}
			});
		}

 
		function recursiveMerge(target, src) {
			for (var prop in src) {
				if (src.hasOwnProperty(prop)) {
					if (target.prototype && target.prototype.constructor === target) {
						// If the target object is a constructor override off prototype.
						clobber(target.prototype, prop, src[prop]);
					} else {
						if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
							recursiveMerge(target[prop], src[prop]);
						} else {
							clobber(target, prop, src[prop]);
						}
					}
				}
			}
		}


		module.exports = {
			buildIntoButDoNotClobber: function(objects, target) {
				include(target, objects, false, false);
			},
			buildIntoAndClobber: function(objects, target) {
				include(target, objects, true, false);
			},
			buildIntoAndMerge: function(objects, target) {
				include(target, objects, true, true);
			},
			recursiveMerge: recursiveMerge,
			assignOrWrapInDeprecateGetter: assignOrWrapInDeprecateGetter
		};

	});

 define("myphonegap/channel",function(require,exports,module){
		var utils = require("myphonegap/utils"),
			nextGuid = 1;
		//典型的創建對象方法:通過構造器初始化變量,從而讓各個實例相互獨立;之後通過修改函數原型共享實例方法。
		var Channel = function(type,sticky){
			this.type = type;
			//map of guid -> function
			this.handlers = {};
			// 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
			this.state = sticky?1:0;
			// Used in sticky mode to remember args passed to fire().
			this.fireArgs = null;
			// Used by onHasSubscribersChange to know if there are any listeners.
			this.numHandlers = 0;
			// Function that is called when the first listener is subscribed, or when
			// the last listener is unsubscribed.
			this.onHasSubscribersChange = null;
	 
		}, channel={
			create:function(type){
				channel[type] = new Channel(type,false);
			},
			createSticky:function(type){
				channel[type] = new Channel(type,true);
			},
			deviceReadyChannelsArray: [],
            deviceReadyChannelsMap: {},
			waitForInitialization: function(feature) {
				if (feature) {
					var c = channel[feature] || this.createSticky(feature);
					this.deviceReadyChannelsMap[feature] = c;
					this.deviceReadyChannelsArray.push(c);
				}
            },
			initializationComplete: function(feature) {
				var c = this.deviceReadyChannelsMap[feature];
				if (c) {
					c.fire();
				}
			},
			join: function (h, c) {//join也就是將一組Channel連接起來,並注入一個在所有Channel上只執行一次的公共處理函數
				var i = c.length;
				var len = i;
				var f = function() {
					if (!(--i)) h();
				};
				for (var j=0; j<len; j++) {
					!c[j].fired?c[j].subscribe(f):i--;
				}
				if (!i) h();
			}
		};
	
		function forceFunction(f){
			if (f === null || f === undefined || typeof f != 'function') throw "Function required as first argument!";
		}
		//給對象Channel的原型對象添加訂閱函數,參數:函數對象、上下文、全局唯一ID
		Channel.prototype.subscribe = function(f,c,g){
			forceFunction(f);//確保f爲函數
			
			if(this.state==2){	//apply方法能劫持另外一個對象的方法,繼承另外一個對象的屬性;f裏面的指針爲c(Channel的實例)
				f.apply(c||this,this.fireArgs);
			}
			
			var func = f,
				guid = f.observer_guid;
			if(typeof f == "object"){ func = utils.close(c,f);}
			
			if(!guid){
				guid = ''+ nextGuid++;
			}
			f.observer_guid = guid;
			func.observer_guid = guid;
			
			//防止重複添加
			if(!this.handlers[guid]){
				this.handlers[guid] = func;
				this.numHandlers++;
				if(this.numHandlers===1){
					this.onHasSubscribersChange&&this.onHasSubscribersChange();
				}
			}
			
		};
		Channel.prototype.unsubscribe = function(f){
			forceFunction(f);
			var guid = f.observer_guid;
			if(this.handlers[guid]){
				delete this.handlers[guid];
				this.numHandlers--;
				if(numHandlers===0){
					this.onHasSubscribersChange&&this.onHasSubscribersChange();
				}
			}
		};
		//訂閱一次
		Channel.prototype.subscribeOnce = function(f,c,g){
		
		};
		//調用了在通道訂閱的所有函數
		Channel.prototype.fire = function(e){
			//console.info('fire start:type/'+this.type + ' numHandlers/' +this.numHandlers); 
			var fail = false,
			fireArgs = Array.prototype.slice.call(arguments);
			// Apply stickiness.
			if (this.state == 1) {
				this.state = 2;
				this.fireArgs = fireArgs;
			}
			if (this.numHandlers) {
				// Copy the values first so that it is safe to modify it from within
				// callbacks.
				var toCall = [];
				for (var item in this.handlers) {
					toCall.push(this.handlers[item]);
				}
				for (var i = 0; i < toCall.length; ++i) {
					toCall[i].apply(this, fireArgs);
					
				//	console.info(this.type+' enter func fire ');
				}
				if (this.state == 2 && this.numHandlers) {
					this.numHandlers = 0;
					this.handlers = {};
					this.onHasSubscribersChange && this.onHasSubscribersChange();
				}
			}
		};
		
		channel.create('onDOMContentLoaded');
		channel.create('onNativeReady');
		channel.create('onDeviceReady');
		
		channel.waitForInitialization('onMyphonegapReady');
		channel.waitForInitialization('onMyphoneConnectionReady');

		module.exports = channel;
		
		//console.info('define myphonegap/channel completed');
	});

  //註冊myphonegap/common模塊
 	//配置對象,將公共模塊組織起來
	define("myphonegap/common",function(require,exports,module){
	
		module.exports = {
			defaults: {
				myphonegap: {
					path: 'myphonegap',
					children: {
						exec: {
							path: 'myphonegap/exec'
						}
					}
				},
				Myphonegap: {
					children: {
						exec: {
							path: 'myphonegap/exec'
						}
					}
				}
			},
			clobbers: {
				navigator: {
					children: {
						connection: {
							path: 'myphonegap/plugin/network'
						}
					}
				}
			}
		};

	});

	define("myphonegap/exec", function(require, exports, module) {
		 /**
		  * 執行cordova命令
		  * 同步:返回一個JSON字符串;異步:返回空字符串"",這個時候可以根據處理結果調用回調函數
		  * 參數:(1)success:命令執行成功回調函數
		  *       (2)fail:命令執行失敗回調函數
		  *       (3)service:使用的服務名稱
		  *       (4)action:在cordova中運行的命令
		  *       (5)args:0或多個參數組成的數組
		  */
		var myphonegap = require('myphonegap');

		module.exports = function(success, fail, service, action, args) {
			try {
				var callbackId = service + myphonegap.callbackId++;//內部回調id
				if (success || fail) {//至少傳入了其中一個
					myphonegap.callbacks[callbackId] = {success:success, fail:fail};
				}

			  //將參數轉化爲JSON字符串去執行
				var r = prompt(JSON.stringify(args), "gap:"+JSON.stringify([service, action, callbackId, true]));
				//alert(r);
		 
				if (r.length > 0) {
					//console.info(r);
					var v = JSON.parse(r);//將返回結果解析成對象
					//console.info(v);
					//console.info(v.status);
					//console.info( myphonegap.callbackStatus.OK);
					if (v.status === myphonegap.callbackStatus.OK) {
						if (success) {//調用成功回調函數
							try {
								success(v.message);
							} catch (e) {
								console.log("Error in success callback: " + callbackId  + " = " + e);
							}

							// 清除回調函數
							if (!v.keepCallback) {
								delete myphonegap.callbacks[callbackId];
							}
						}
						return v.message;
					}
					else if (v.status === myphonegap.callbackStatus.NO_RESULT) {
						// 清除回調函數
						if (!v.keepCallback) {
							delete myphonegap.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 myphonegap.callbacks[callbackId];
							}
						}
						return null;
					}
				}
			} catch (e2) {
				console.log("Error: "+e2);
			}
		};

	});

  //註冊myphonegap/platform模塊
  define("myphonegap/platform", function(require, exports, module){
		module.exports = {
			id: "android",
			initialize:function() {
				 
			},
			clobbers: { //需要覆蓋的屬性
				navigator: {
					children: {
						app:{
							path: "myphonegap/plugin/android/app"
						}
					}
				},
			   //省略
				open: {
					path: "myphonegap/plugin/InAppBrowser"
				}
			},
			merges: { //需要合併的屬性
				device: {
					path: 'myphonegap/plugin/android/device'
				},
				navigator: {
					children: {
						notification: {
							path: 'myphonegap/plugin/android/notification'
						}
					}
				}
			}
		}
  });

  // 這裏省略了其它插件的註冊

  //註冊myphonegap/utils模塊
  define("myphonegap/utils", function(require, exports, module){
		var utils = exports;

		 
		utils.defineGetterSetter = function(obj, key, getFunc, opt_setFunc) {
			if (Object.defineProperty) {
				var desc = {
					get: getFunc,
					configurable: true
				};
				if (opt_setFunc) {
					desc.set = opt_setFunc;
				}
				Object.defineProperty(obj, key, desc);
			} else {
				obj.__defineGetter__(key, getFunc);
				if (opt_setFunc) {
					obj.__defineSetter__(key, opt_setFunc);
				}
			}
		};
		 
		utils.defineGetter = utils.defineGetterSetter;
		
		utils.alert = function(msg) {
			if (window.alert) {
				window.alert(msg);
			} else if (console && console.log) {
				console.log(msg);
			}
		};

	});

	(function (context) {
		// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
		// We replace it so that properties that can't be clobbered can instead be overridden.
		if (context.navigator) {
			var CordovaNavigator = function() {};
			CordovaNavigator.prototype = context.navigator;
			context.navigator = new CordovaNavigator();
		}

		var channel = require("myphonegap/channel"),
			_self = {
				boot: function () {
					/**
					 * Create all cordova objects once page has fully loaded and native side is ready.
					 */
					channel.join(function() {
						var builder = require('myphonegap/builder'),
							base = require('myphonegap/common'),
							platform = require('myphonegap/platform');

						// Drop the common globals into the window object, but be nice and don't overwrite anything.
						builder.buildIntoButDoNotClobber(base.defaults, context);
						builder.buildIntoAndClobber(base.clobbers, context);
						builder.buildIntoAndMerge(base.merges, context);

						builder.buildIntoButDoNotClobber(platform.defaults, context);
						builder.buildIntoAndClobber(platform.clobbers, context);
						builder.buildIntoAndMerge(platform.merges, context);

						// Call the platform-specific initialization
						platform.initialize();

						// Fire event to notify that all objects are created
						channel.onCordovaReady.fire();

						// Fire onDeviceReady event once all constructors have run and
						// myphonegap info has been received from native side.
						channel.join(function() {
							require('myphonegap').fireDocumentEvent('deviceready');
						}, channel.deviceReadyChannelsArray);

					}, [ channel.onNativeReady,channel.onDOMContentLoaded ]);
				}
			};

		// boot up once native side is ready
		channel.onNativeReady.subscribe(_self.boot);

		// _nativeReady is global variable that the native side can set
		// to signify that the native code is ready. It is a global since
		// it may be called before any cordova JS is ready.
		if (window._nativeReady) {
			channel.onNativeReady.fire();
		}

	}(window));
  //所有模塊註冊完之後,再導入cordova至全局環境中
  window.myphonegap = require('myphonegap');
	window.myphonegap.Hello("wen");
	
	//測試channel模塊
	/*
	var channel = require("myphonegap/channel");
		channel.onNativeReady.subscribe(function(){
			console.info("onNativeReady");
		}
	);
	console.info("before native ready");
	channel.onNativeReady.fire();
	console.info("after native ready");
	*/
	
	/* 
	//測試common模塊與builder模塊
	var builder = require("myphonegap/builder");
	var common  = require("myphonegap/common"); 
	
	builder.buildIntoButDoNotClobber( common.defaults,window);
	
	window.myphonegap.Hello("Jack");
	window.myphonegap.exec("myfunc");
	*/
	
	//測試初始化函數
	
	
	//測試exec模塊
	var exec = require("myphonegap/exec");
	exec(function(ret){console.info("plus exec success!");console.info("15+15=" + ret)}, 
				function(){console.info("multiply exec failed!")}, 'Math', 'plus',15);
				
	exec(function(ret){console.info("multiply exec success!");console.info("15*15=" + ret)}, 
			function(){console.info("multiply exec failed!")}, 'Math', 'multiply',15);
})();


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章