Implement the online events based Native->JS bridge.

This commit is contained in:
Andrew Grieve 2012-08-21 14:15:04 -04:00
parent 7fa4515c28
commit e239fd970f
2 changed files with 79 additions and 62 deletions

View File

@ -198,7 +198,7 @@ public class CordovaWebView extends WebView {
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private void setup() {
jsMessageQueue = new NativeToJsMessageQueue(this);
jsMessageQueue = new NativeToJsMessageQueue(this, cordova);
this.setInitialScale(0);
this.setVerticalScrollBarEnabled(false);

View File

@ -20,6 +20,8 @@ package org.apache.cordova;
import java.util.LinkedList;
import org.apache.cordova.api.CordovaInterface;
import android.util.Log;
/**
@ -31,26 +33,32 @@ public class NativeToJsMessageQueue {
// This must match the default value in incubator-cordova-js/lib/android/exec.js
private static final int DEFAULT_BRIDGE_MODE = 1;
/**
* The list of JavaScript statements to be sent to JavaScript.
*/
private LinkedList<String> queue = new LinkedList<String>();
/**
* The index into registeredListeners to treat as active.
*/
private int activeListenerIndex;
/**
* The list of JavaScript statements to be sent to JavaScript.
*/
private final LinkedList<String> queue = new LinkedList<String>();
/**
* The array of listeners that can be used to send messages to JS.
*/
private BridgeMode[] registeredListeners;
private final BridgeMode[] registeredListeners;
public NativeToJsMessageQueue(CordovaWebView webView) {
registeredListeners = new BridgeMode[3];
private final CordovaInterface cordova;
private final CordovaWebView webView;
public NativeToJsMessageQueue(CordovaWebView webView, CordovaInterface cordova) {
this.cordova = cordova;
this.webView = webView;
registeredListeners = new BridgeMode[4];
registeredListeners[0] = null;
registeredListeners[1] = new CallbackBridgeMode(webView);
registeredListeners[2] = new LoadUrlBridgeMode(webView);
registeredListeners[1] = new CallbackBridgeMode();
registeredListeners[2] = new LoadUrlBridgeMode();
registeredListeners[3] = new OnlineEventsBridgeMode();
reset();
// POLLING: 0,
// HANGING_GET: 1,
@ -72,7 +80,7 @@ public class NativeToJsMessageQueue {
activeListenerIndex = value;
BridgeMode activeListener = registeredListeners[value];
if (!queue.isEmpty() && activeListener != null) {
activeListener.onNativeToJsMessageAvailable(this);
activeListener.onNativeToJsMessageAvailable();
}
}
}
@ -140,37 +148,46 @@ public class NativeToJsMessageQueue {
synchronized (this) {
queue.add(statement);
if (registeredListeners[activeListenerIndex] != null) {
registeredListeners[activeListenerIndex].onNativeToJsMessageAvailable(this);
registeredListeners[activeListenerIndex].onNativeToJsMessageAvailable();
}
}
}
private interface BridgeMode {
void onNativeToJsMessageAvailable(NativeToJsMessageQueue queue);
void onNativeToJsMessageAvailable();
}
/** Uses a local server to send messages to JS via an XHR */
private static class CallbackBridgeMode implements BridgeMode {
private CordovaWebView webView;
public CallbackBridgeMode(CordovaWebView webView) {
this.webView = webView;
}
public void onNativeToJsMessageAvailable(NativeToJsMessageQueue queue) {
private class CallbackBridgeMode implements BridgeMode {
public void onNativeToJsMessageAvailable() {
if (webView.callbackServer != null) {
webView.callbackServer.onNativeToJsMessageAvailable(queue);
webView.callbackServer.onNativeToJsMessageAvailable(NativeToJsMessageQueue.this);
}
}
}
/** Uses webView.loadUrl("javascript:") to execute messages. */
public static class LoadUrlBridgeMode implements BridgeMode {
private CordovaWebView webView;
public LoadUrlBridgeMode(CordovaWebView webView) {
this.webView = webView;
}
public void onNativeToJsMessageAvailable(NativeToJsMessageQueue queue) {
webView.loadUrlNow("javascript:" + queue.popAll());
public class LoadUrlBridgeMode implements BridgeMode {
public void onNativeToJsMessageAvailable() {
webView.loadUrlNow("javascript:" + popAll());
}
}
/** Uses online/offline events to tell the JS when to poll for messages. */
public class OnlineEventsBridgeMode implements BridgeMode {
boolean online = true;
final Runnable runnable = new Runnable() {
@Override
public void run() {
if (!queue.isEmpty()) {
online = !online;
webView.setNetworkAvailable(online);
}
}
};
public void onNativeToJsMessageAvailable() {
cordova.getActivity().runOnUiThread(runnable);
}
}
}