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/08/22 15:57:11 UTC

[5/6] android commit: Implement the online events based Native->JS bridge.

Implement the online events based Native->JS bridge.


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/e239fd97
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/tree/e239fd97
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/diff/e239fd97

Branch: refs/heads/master
Commit: e239fd970f836285ffe11fd5387c7db87f764a74
Parents: 7fa4515
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Aug 21 14:15:04 2012 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Aug 22 09:46:30 2012 -0400

----------------------------------------------------------------------
 .../src/org/apache/cordova/CordovaWebView.java     |    2 +-
 .../org/apache/cordova/NativeToJsMessageQueue.java |  139 ++++++++-------
 2 files changed, 79 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/e239fd97/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java
index 131f754..7e78de8 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -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);

http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/e239fd97/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 6abb970..e9f093a 100755
--- a/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
+++ b/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
@@ -20,6 +20,8 @@ package org.apache.cordova;
 
 import java.util.LinkedList;
 
+import org.apache.cordova.api.CordovaInterface;
+
 import android.util.Log;
 
 /**
@@ -32,26 +34,32 @@ public class NativeToJsMessageQueue {
     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;    
+    
+    private final CordovaInterface cordova;
+    private final CordovaWebView webView;
         
-    public NativeToJsMessageQueue(CordovaWebView webView) {
-    	registeredListeners = new BridgeMode[3];
-    	registeredListeners[0] = null;
-    	registeredListeners[1] = new CallbackBridgeMode(webView);
-    	registeredListeners[2] = new LoadUrlBridgeMode(webView);
-    	reset();
+    public NativeToJsMessageQueue(CordovaWebView webView, CordovaInterface cordova) {
+        this.cordova = cordova;
+        this.webView = webView;
+        registeredListeners = new BridgeMode[4];
+        registeredListeners[0] = null;
+        registeredListeners[1] = new CallbackBridgeMode();
+        registeredListeners[2] = new LoadUrlBridgeMode();
+        registeredListeners[3] = new OnlineEventsBridgeMode();
+        reset();
 //        POLLING: 0,
 //        HANGING_GET: 1,
 //        LOAD_URL: 2,
@@ -63,30 +71,30 @@ public class NativeToJsMessageQueue {
      * Changes the bridge mode.
      */
     public void setBridgeMode(int value) {
-    	if (value < 0 || value >= registeredListeners.length) {
-    		Log.d(LOG_TAG, "Invalid NativeToJsBridgeMode: " + value);
-    	} else {
-    		if (value != activeListenerIndex) {
-    			Log.d(LOG_TAG, "Set native->JS mode to " + value);
-    			synchronized (this) {
-    			    activeListenerIndex = value;
-    			    BridgeMode activeListener = registeredListeners[value];
-    			    if (!queue.isEmpty() && activeListener != null) {
-    			    	activeListener.onNativeToJsMessageAvailable(this);
-    			    }
-    			}
-    		}
-    	}
+        if (value < 0 || value >= registeredListeners.length) {
+            Log.d(LOG_TAG, "Invalid NativeToJsBridgeMode: " + value);
+        } else {
+            if (value != activeListenerIndex) {
+                Log.d(LOG_TAG, "Set native->JS mode to " + value);
+                synchronized (this) {
+                    activeListenerIndex = value;
+                    BridgeMode activeListener = registeredListeners[value];
+                    if (!queue.isEmpty() && activeListener != null) {
+                        activeListener.onNativeToJsMessageAvailable();
+                    }
+                }
+            }
+        }
     }
     
-	/**
-	 * Clears all messages and resets to the default bridge mode.
+    /**
+     * Clears all messages and resets to the default bridge mode.
      */
     public void reset() {
-    	synchronized (this) {
-    		queue.clear();
-    		setBridgeMode(DEFAULT_BRIDGE_MODE);
-    	}
+        synchronized (this) {
+            queue.clear();
+            setBridgeMode(DEFAULT_BRIDGE_MODE);
+        }
     }
 
     /**
@@ -116,17 +124,17 @@ public class NativeToJsMessageQueue {
             // Wrap each statement in a try/finally so that if one throws it does 
             // not affect the next.
             int i = 0;
-			for (String message : queue) {
-            	if (++i == length) {
-            		sb.append(message);
-            	} else {
-	            	sb.append("try{")
-	            	  .append(message)
-	            	  .append("}finally{");
-            	}
+            for (String message : queue) {
+                if (++i == length) {
+                    sb.append(message);
+                } else {
+                    sb.append("try{")
+                      .append(message)
+                      .append("}finally{");
+                }
             }
             for ( i = 1; i < length; ++i) {
-            	sb.append('}');
+                sb.append('}');
             }
             queue.clear();
             return sb.toString();
@@ -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) {
-    		if (webView.callbackServer != null) {
-    			webView.callbackServer.onNativeToJsMessageAvailable(queue);
-    		}
+    private class CallbackBridgeMode implements BridgeMode {
+        public void onNativeToJsMessageAvailable() {
+            if (webView.callbackServer != null) {
+                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);
+        }
+    }
 }