On Github zfkun / cordova-intro
Native Bridge
// CordovaWebView.java pluginManager = new PluginManager(this, this.cordova); jsMessageQueue = new NativeToJsMessageQueue(this, cordova); exposedJsApi = new ExposedJsApi(pluginManager, jsMessageQueue); resourceApi = new CordovaResourceApi(this.getContext(), pluginManager); exposeJsInterface();
// exposeJsInterface() this.addJavascriptInterface(exposedJsApi, "_cordovaNative");
// similar in ActionScript ExternalInterface.addCallback("say", this._say);
Prompt (2.3 simulator, 3.2-)
'cordova/android/promptbasednativeapi'
JS Object (addJavascriptInterface)
get NativeApi
nativeApiProvider = require('cordova/android/nativeapiprovider'); nativeApiProvider.get()
NativeApi Provider
var nativeApi = this._cordovaNative || require('cordova/android/promptbasednativeapi');
Location Change (CordovaWebViewClient)
This mode is currently for benchmarking purposes only
// NativeToJsMessageQueue.java ENABLE_LOCATION_CHANGE_EXEC_MODE = true;
window.location = 'http://cdv_exec/' + service + '#' + action + '#' + callbackId + '#' + argsJson;
onJsPrompt
boolean reqOk = false; if (url.startsWith("file://") || Config.isUrlWhiteListed(url)) { reqOk = true; }
// Synchronous: 'gap:*', 'gap_poll:', 'gap_init:' String r = this.appView.exposedJsApi.exec(..); // -> PluginManager.exec() result.confirm(r == null ? "" : r); // JsPromptResult // Asynchronous: 'gap_bridge_mode:' result.confirm(''); // JsPromptResult
// PluginManager.java exec(..) -> app.sendPluginResult(..) -> CordovaWebView
// CordovaWebView.java this.jsMessageQueue.addPluginResult(..) -> NativeToJsMessageQueue
// NativeToJsMessageQueue.java [?BridgeMode].onNativeToJsMessageAvailable(..) // make encoded JS sb.append("window.setTimeout(function(){cordova.require('cordova/plugin/android/polling').pollOnce();},0);");
// OnlineEventsBridgeMode webView.setNetworkAvailable(online); // LoadUrlBridgeMode webView.loadUrlNow("javascript:" + js); // PrivateApiBridgeMode (Android 3.2.4+) sendMessageMethod = webViewCore.getClass().getDeclaredMethod("sendMessage", Message.class); sendMessageMethod.invoke(webViewCore, execJsMessage);
// This is called from the NativeToJsMessageQueue.java. androidExec.processMessages = function(messages) {..};
OnlineEventsBridge - 'cordova/exec'
window.addEventListener('online', pollOnceFromOnlineEvent, false); window.addEventListener('offline', pollOnceFromOnlineEvent, false); function pollOnceFromOnlineEvent() { pollOnce(true); } function pollOnce(opt_fromOnlineEvent) { var msg = nativeApiProvider.get().retrieveJsMessages(!!opt_fromOnlineEvent); androidExec.processMessages(msg); } function pollingTimerFunc() { if (pollEnabled) { pollOnce(); setTimeout(pollingTimerFunc, 50); } }
iFrame
nav (fastest)
var command = [callbackId, service, action, actionArgs]; commandQueue.push(JSON.stringify(command)); execIframe.src = "gap://ready";
hash
execHashIframe.contentWindow.location.hash = hashValue;
XMLHttpRequest (5.x)
execXhr.open('HEAD', "/!gap_exec?" + (+new Date()), true); execXhr.setRequestHeader('cmds', iOSExec.nativeFetchMessages());
ViewController
// shouldStartLoadWithRequest:navigationType: if ([[url scheme] isEqualToString:@"gap"]) { [_commandQueue fetchCommandsFromJs]; [_commandQueue executePending]; return NO; }
CommandQueue
- (void)fetchCommandsFromJs { NSString* queuedCommandsJSON = [_viewController.webView stringByEvaluatingJavaScriptFromString: @"cordova.require('cordova/exec').nativeFetchMessages()"]; }
Plugin
- (NSString*)writeJavascript:(NSString*)javascript { return [self.webView stringByEvaluatingJavaScriptFromString:javascript]; }
external.Notify()
var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args); window.external.Notify(command);
ScriptNotify
void CordovaBrowser_ScriptNotify(object sender, NotifyEventArgs e) { .. }
NativeExecution
// NativeExecution.cs private void InvokeScriptCallback(ScriptCallback script) { this.webBrowser.InvokeScript(script.ScriptName, script.Args); }
WebBrowser
// WebBrowser.cs public Object InvokeScript(String scriptName, params Object[] args) { .. }
XMLHttpRequest
Sync / Async
function RemoteFunctionCall(functionUri) { .. function composeUri() { return "http://localhost:8472/" + functionUri; } .. }
function createXhrRequest(uri, isAsync) { .. request.open("POST", uri, isAsync); request.setRequestHeader("Content-Type", "application/json"); .. } response = JSON.parse(decodeURIComponent(request.responseText) || "null");
Native
webview.js
var requestObj = networkResourceRequested.createHandler(_webviewObj); _webviewObj.onNetworkResourceRequested = requestObj.networkResourceRequestedHandler;
networkResourceRequested.js
module.exports = { createHandler: function (webview) { return new NetworkResourceRequestHandler(webview); } };
executeJavaScript
this.webview.executeJavaScript('');
PluginResult
var executeString = "cordova.callbackFromNative('" + callbackId + "', " + !!success + ", " + status + ", [" + data + "], " + !!keepCallback + ");"; env.webview.executeJavaScript(executeString);
no Cordova API
Chrome / Safari / Firefox
open -a "Google Chrome.app" --args --disable-web-security --allow-file-access-from-files
F12 / Alt + Command + J
Apache Ripple™
npm install -g ripple-emulator
ripple emulate --path path/to/app
ripple emulate --remote http://mytest.com
adb logcat
adb logcat -s CordovaWebViewClient
DDMS (Dalvik Debug Monitor Service)
{Andriod SDK Home}/tools/monitor
Debug Target(phone) <=> Debug Server <=> Debug Client(PC)
WEb INspector REmote ['waɪnəri]
sudo npm -g install weinre
weinre --boundHost 192.168.1.2 --httpPort 8888
//192.168.1.2:8888/target/target-script-min.js
http://192.168.1.2:8888
http://debug.phonegap.com
bd
<script src="//debug.phonegap.com/target/target-script-min.js#bd"></script>
http://debug.phonegap.com/client/#bd
just for iOS 5.0 && 5.1
[NSClassFromString(@"WebView") _enableRemoteInspector];
Web debugging tool for iOS Simuator
基于新浪移动云的移动应用
PhoneGap 1.8-
支持版本不详
Preview & inspect web designs on devices
via `index.html` from local server
<content src="http://192.168.1.2:8000/index.html"></content>
cordova run *** (platform)
but, doen't work (only iOS emulator)...