Use polling instead of XHR for callbacks from Java to JavaScript when device has a proxy set.

This commit is contained in:
Bryce Curtis 2010-10-26 15:09:54 -05:00
parent f63b8140af
commit bc1e039ea1
3 changed files with 75 additions and 8 deletions

View File

@ -238,7 +238,14 @@ PhoneGap.onDeviceReady = new PhoneGap.Channel('onDeviceReady');
PhoneGap.Channel.join(function() {
// Start listening for XHR callbacks
setTimeout(function() {
if (CallbackServer.usePolling()) {
PhoneGap.JSCallbackPolling();
}
else {
PhoneGap.JSCallback();
}
}, 1);
// Run PhoneGap constructors
PhoneGap.onPhoneGapInit.fire();
@ -603,6 +610,37 @@ PhoneGap.JSCallback = function() {
xmlhttp.send();
};
/**
* The polling period to use with JSCallbackPolling.
* This can be changed by the application. The default is 50ms.
*/
PhoneGap.JSCallbackPollingPeriod = 50;
/**
* This is only for Android.
*
* Internal function that uses polling to call into PhoneGap Java code and retrieve
* any JavaScript code that needs to be run. This is used for callbacks from
* Java to JavaScript.
*/
PhoneGap.JSCallbackPolling = function() {
var msg = CallbackServer.getJavascript();
if (msg) {
setTimeout(function() {
try {
var t = eval(""+msg);
}
catch (e) {
console.log("JSCallbackPolling Error: "+e);
}
}, 1);
setTimeout(PhoneGap.JSCallbackPolling, 1);
}
else {
setTimeout(PhoneGap.JSCallbackPolling, PhoneGap.JSCallbackPollingPeriod);
}
};
/**
* Create a UUID
*

View File

@ -17,10 +17,10 @@ import java.util.LinkedList;
/**
* This class provides a way for Java to run JavaScript in the web page that has loaded PhoneGap.
* The CallbackServer class implements an XHR server and a list of JavaScript statements
* that are to be executed on the web page.
* The CallbackServer class implements an XHR server and a polling server with a list of JavaScript
* statements that are to be executed on the web page.
*
* The process flow is:
* The process flow for XHR is:
* 1. JavaScript makes an async XHR call.
* 2. The server holds the connection open until data is available.
* 3. The server writes the data to the client and closes the connection.
@ -30,6 +30,14 @@ import java.util.LinkedList;
*
* The CallbackServer class requires the following permission in Android manifest file
* <uses-permission android:name="android.permission.INTERNET" />
*
* If the device has a proxy set, then XHR cannot be used, so polling must be used instead.
* This can be determined by the client by calling CallbackServer.usePolling().
*
* The process flow for polling is:
* 1. The client calls CallbackServer.getJavascript() to retrieve next statement.
* 2. If statement available, then client processes it.
* 3. The client repeats #1 in loop.
*/
public class CallbackServer implements Runnable {
@ -58,6 +66,11 @@ public class CallbackServer implements Runnable {
*/
private boolean empty;
/**
* Indicates that polling should be used instead of XHR.
*/
private boolean usePolling;
/**
* Constructor.
*/
@ -67,8 +80,24 @@ public class CallbackServer implements Runnable {
this.empty = true;
this.port = 0;
this.javascript = new LinkedList<String>();
if (android.net.Proxy.getDefaultHost() != null) {
this.usePolling = true;
}
else {
this.usePolling = false;
this.startServer();
}
}
/**
* Determine if polling should be used instead of XHR.
*
* @return
*/
public boolean usePolling() {
return this.usePolling;
}
/**
* Get the port that this server is running on.

View File

@ -99,7 +99,7 @@ public abstract class Plugin implements IPlugin {
* @param statement
*/
public void sendJavascript(String statement) {
this.ctx.callbackServer.sendJavascript(statement);
this.ctx.sendJavascript(statement);
}
/**
@ -113,7 +113,7 @@ public abstract class Plugin implements IPlugin {
* @param callbackId The callback id used when calling back into JavaScript.
*/
public void success(PluginResult pluginResult, String callbackId) {
this.ctx.callbackServer.sendJavascript(pluginResult.toSuccessCallbackString(callbackId));
this.ctx.sendJavascript(pluginResult.toSuccessCallbackString(callbackId));
}
/**
@ -123,6 +123,6 @@ public abstract class Plugin implements IPlugin {
* @param callbackId The callback id used when calling back into JavaScript.
*/
public void error(PluginResult pluginResult, String callbackId) {
this.ctx.callbackServer.sendJavascript(pluginResult.toErrorCallbackString(callbackId));
this.ctx.sendJavascript(pluginResult.toErrorCallbackString(callbackId));
}
}