Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PhoneGap plugin: fastest way to transfer JSON data to native

Tags:

I have been working on a PhoneGap plugin to enable WebGL, intended for publishing HTML5 games to mobile. It's called WebGLGap. However, PhoneGap's way of calling plugin code (via exec) typically involves stringifying all the parameters to JSON, then parsing it on the other side again. According to this question, this has not changed even in PhoneGap 2.2 which was advertised as having a faster bridge. For something like WebGL, this is absolutely untenable and kills performance (<10 FPS) even for simple demos. This is because in many cases, especially 2D games, every frame must transmit a large block of JSON data representing all the WebGL commands to run. This includes all vertex data - imagine a huge string of "0.959455, 0.959595, 0.588575, 0.585858..." etc every frame.

Obviously stringifying and parsing is an unnecessary and inefficient step, but I'm struggling to find a way to pass the JSON data from JS to native which avoids that. Ideally this should work on both Android and iOS, but I'm happy to stick to an Android-only solution for now. Does anyone have any ideas about the most efficient way to do this?

like image 574
AshleysBrain Avatar asked Nov 19 '12 18:11

AshleysBrain


2 Answers

Linkedin use Web Sockets for their iPad app. Might be worth looking into: http://engineering.linkedin.com/mobile/linkedin-ipad-nativeweb-messaging-bridge-and-websockets

Some of the benefits that you're looking for

  • WebSockets can communicate asynchronously from JavaScript to native.
  • WebSockets don't have a payload limit
  • WebSockets don't require us to encode our JSON strings as URL parameters
  • WebSockets should be faster than URL scheme navigation
like image 115
sciritai Avatar answered Oct 18 '22 07:10

sciritai


Addressing performance

Looking at CordovaPlugin.java, as you mentioned, everything is a String:

public boolean execute(String action, String rawArgs, CallbackContext callbackContext) throws JSONException {
    JSONArray args = new JSONArray(rawArgs);
    return execute(action, args, callbackContext);
}

If, for example, the conversion from String to JSONArray is the only bottleneck, then you could override this method in your plugin and perform your own deserialization. It's a small performance improvement, but it might be worth investigating.

Creating an alternate bridge

As for creating an alternative bridge, that's trickier. I don't know much about Cordova / PhoneGap, but from what research I've gathered, Cordova exposes a specific Javascript interface via addJavascriptInterface. If you could implement your own NativetoJSMessageQueue, you might be able to wire it all together.

EDIT
After conducting a bit more research, I can provide a bit more direction. The really relevant part of the NativetoJSMessageQueue is the various BridgeModes it implements (see line 92). You could look at the other bridge modes as an example.

Unfortunately, the NativetoJSMessageQueue has exactly four bridge modes registered; assuming that you could implement your own bridge mode, you would still need to some how register it as a new mode for the NativetoJSMessageQueue.

like image 28
NT3RP Avatar answered Oct 18 '22 09:10

NT3RP