You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2012/09/18 19:52:51 UTC
[10/14] android commit: Always send as many messages native->JS in
one payload as possible.
Always send as many messages native->JS in one payload as possible.
Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/commit/f53161d6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/tree/f53161d6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/diff/f53161d6
Branch: refs/heads/master
Commit: f53161d6f54ecca2aef9f96d35eaf12d39ef6bf9
Parents: 4c9a571
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Sep 11 14:35:39 2012 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Sep 18 13:24:37 2012 -0400
----------------------------------------------------------------------
.../src/org/apache/cordova/CallbackServer.java | 1 -
framework/src/org/apache/cordova/ExposedJsApi.java | 2 -
.../org/apache/cordova/NativeToJsMessageQueue.java | 73 +++++++++------
3 files changed, 43 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/f53161d6/framework/src/org/apache/cordova/CallbackServer.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CallbackServer.java b/framework/src/org/apache/cordova/CallbackServer.java
index 7cefe3b..0b8383c 100755
--- a/framework/src/org/apache/cordova/CallbackServer.java
+++ b/framework/src/org/apache/cordova/CallbackServer.java
@@ -214,7 +214,6 @@ public class CallbackServer implements Runnable {
synchronized (this) {
while (this.active) {
if (jsMessageQueue != null) {
- // TODO(agrieve): Should this use popAll() instead?
payload = jsMessageQueue.popAndEncode();
if (payload != null) {
break;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/f53161d6/framework/src/org/apache/cordova/ExposedJsApi.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/ExposedJsApi.java b/framework/src/org/apache/cordova/ExposedJsApi.java
index daef571..b96ec64 100755
--- a/framework/src/org/apache/cordova/ExposedJsApi.java
+++ b/framework/src/org/apache/cordova/ExposedJsApi.java
@@ -41,7 +41,6 @@ import org.json.JSONException;
jsMessageQueue.setPaused(true);
try {
pluginManager.exec(service, action, callbackId, arguments, true /* async */);
- // TODO(agrieve): Should this use popAll() instead?
return jsMessageQueue.popAndEncode();
} finally {
jsMessageQueue.setPaused(false);
@@ -53,7 +52,6 @@ import org.json.JSONException;
}
public String retrieveJsMessages() {
- // TODO(agrieve): Should this use popAll() instead?
return jsMessageQueue.popAndEncode();
}
}
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/f53161d6/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/NativeToJsMessageQueue.java b/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
index a118706..807e87e 100755
--- a/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
+++ b/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
@@ -24,7 +24,6 @@ import java.util.LinkedList;
import org.apache.cordova.api.CordovaInterface;
import org.apache.cordova.api.PluginResult;
-import org.json.JSONObject;
import android.os.Message;
import android.util.Log;
@@ -43,6 +42,9 @@ public class NativeToJsMessageQueue {
// JS instead of the custom format (useful for benchmarking).
private static final boolean FORCE_ENCODE_USING_EVAL = false;
+ // Arbitrarily chosen upper limit for how much data to send to JS in one shot.
+ private static final int MAX_PAYLOAD_SIZE = 50 * 1024;
+
/**
* The index into registeredListeners to treat as active.
*/
@@ -121,58 +123,67 @@ public class NativeToJsMessageQueue {
message.encodeAsMessage(sb);
}
- public String popAndEncode() {
- synchronized (this) {
- if (queue.isEmpty()) {
- return null;
- }
- JsMessage message = queue.removeFirst();
- StringBuilder sb = new StringBuilder(calculatePackedMessageLength(message));
- packMessage(message, sb);
- return sb.toString();
- }
- }
-
/**
- * Combines and returns all messages combined into a single string.
- * Clears the queue.
+ * Combines and returns queued messages combined into a single string.
+ * Combines as many messages as possible, while staying under MAX_PAYLOAD_SIZE.
* Returns null if the queue is empty.
*/
- public String popAllAndEncode() {
+ public String popAndEncode() {
synchronized (this) {
if (queue.isEmpty()) {
return null;
}
int totalPayloadLen = 0;
+ int numMessagesToSend = 0;
for (JsMessage message : queue) {
- totalPayloadLen += calculatePackedMessageLength(message);
+ int messageSize = calculatePackedMessageLength(message);
+ if (numMessagesToSend > 0 && totalPayloadLen + messageSize > MAX_PAYLOAD_SIZE) {
+ break;
+ }
+ totalPayloadLen += messageSize;
+ numMessagesToSend += 1;
}
StringBuilder sb = new StringBuilder(totalPayloadLen);
- for (JsMessage message : queue) {
+ for (int i = 0; i < numMessagesToSend; ++i) {
+ JsMessage message = queue.removeFirst();
packMessage(message, sb);
}
- queue.clear();
+
+ if (!queue.isEmpty()) {
+ // Attach a char to indicate that there are more messages pending.
+ sb.append('*');
+ }
return sb.toString();
}
}
- private String popAllAndEncodeAsJs() {
+ /**
+ * Same as popAndEncode(), except encodes in a form that can be executed as JS.
+ */
+ private String popAndEncodeAsJs() {
synchronized (this) {
int length = queue.size();
if (length == 0) {
return null;
}
- int totalPayloadLen = 16 * length; // accounts for try & finally.
+ int totalPayloadLen = 0;
+ int numMessagesToSend = 0;
for (JsMessage message : queue) {
- totalPayloadLen += message.calculateEncodedLength(); // overestimate.
+ int messageSize = message.calculateEncodedLength() + 50; // overestimate.
+ if (numMessagesToSend > 0 && totalPayloadLen + messageSize > MAX_PAYLOAD_SIZE) {
+ break;
+ }
+ totalPayloadLen += messageSize;
+ numMessagesToSend += 1;
}
- StringBuilder sb = new StringBuilder(totalPayloadLen);
+ boolean willSendAllMessages = numMessagesToSend == queue.size();
+ StringBuilder sb = new StringBuilder(totalPayloadLen + (willSendAllMessages ? 0 : 100));
// Wrap each statement in a try/finally so that if one throws it does
// not affect the next.
- int i = 0;
- for (JsMessage message : queue) {
- if (++i == length) {
+ for (int i = 0; i < numMessagesToSend; ++i) {
+ JsMessage message = queue.removeFirst();
+ if (willSendAllMessages && (i + 1 == numMessagesToSend)) {
message.encodeAsJsMessage(sb);
} else {
sb.append("try{");
@@ -180,10 +191,12 @@ public class NativeToJsMessageQueue {
sb.append("}finally{");
}
}
- for ( i = 1; i < length; ++i) {
+ if (!willSendAllMessages) {
+ sb.append("window.setTimeout(function(){cordova.require('cordova/plugin/android/polling').pollOnce();},0);");
+ }
+ for (int i = willSendAllMessages ? 1 : 0; i < numMessagesToSend; ++i) {
sb.append('}');
}
- queue.clear();
return sb.toString();
}
}
@@ -262,7 +275,7 @@ public class NativeToJsMessageQueue {
private class LoadUrlBridgeMode implements BridgeMode {
final Runnable runnable = new Runnable() {
public void run() {
- String js = popAllAndEncodeAsJs();
+ String js = popAndEncodeAsJs();
if (js != null) {
webView.loadUrlNow("javascript:" + js);
}
@@ -344,7 +357,7 @@ public class NativeToJsMessageQueue {
}
// webViewCore is lazily initialized, and so may not be available right away.
if (sendMessageMethod != null) {
- String js = popAllAndEncodeAsJs();
+ String js = popAndEncodeAsJs();
Message execJsMessage = Message.obtain(null, EXECUTE_JS, js);
try {
sendMessageMethod.invoke(webViewCore, execJsMessage);