PhoneGap插件:将JSON数据传输到本机的最快方法

时间:2012-11-19 18:40:12

标签: javascript android cordova phonegap-plugins

我一直在开发一个PhoneGap插件来启用WebGL,用于将HTML5游戏发布到移动设备。它被称为WebGLGap。但是,PhoneGap调用插件代码的方式(通过exec)通常涉及将所有参数字符串化为JSON,然后再次在另一端解析它。根据{{​​3}},即使在PhoneGap 2.2中也没有改变,因为它被宣传为具有更快的桥接。对于像WebGL这样的东西,这是绝对站不住脚的,即使对于简单的演示也会杀死性能(<10 FPS)。这是因为在许多情况下,特别是2D游戏,每个帧必须传输一大块JSON数据,表示要运行的所有WebGL命令。这包括所有顶点数据 - 想象每一帧都有一大串“0.959455,0.959595,0.588575,0.585858 ......”等。

显然,字符串化和解析是一个不必要且低效的步骤,但我很难找到一种方法将JSON数据从JS传递给本机,这避免了这种情况。理想情况下,这应该适用于Android和iOS,但我很高兴现在坚持使用仅限Android的解决方案。有没有人对最有效的方法有任何想法?

6 个答案:

答案 0 :(得分:12)

Linkedin使用Web套接字为他们的iPad应用程序。可能值得研究:http://engineering.linkedin.com/mobile/linkedin-ipad-nativeweb-messaging-bridge-and-websockets

您正在寻找的一些好处

  • WebSockets可以从JavaScript异步通信到本机。
  • WebSockets没有有效负载限制
  • WebSockets不要求我们将JSON字符串编码为URL参数
  • WebSockets应该比URL方案导航更快

答案 1 :(得分:3)

解决绩效

如您所述,查看CordovaPlugin.java,所有内容都是String

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

例如,如果从StringJSONArray的转换是唯一的瓶颈,那么您可以在插件中覆盖此方法并执行自己的反序列化。这是一个小的性能改进,但它可能值得调查。

创建备用桥梁

至于创建另类桥梁,这更棘手。我对Cordova / PhoneGap了解不多,但从我收集的研究Cordova exposes a specific Javascript interfaceaddJavascriptInterface。如果您可以实现自己的NativetoJSMessageQueue,则可以将它们连接在一起。

修改
在进行了一些研究之后,我可以提供更多的方向。 NativetoJSMessageQueue的真正相关部分是它实现的各种BridgeModes(参见line 92)。您可以查看其他桥接模式作为示例。

不幸的是,NativetoJSMessageQueue正好注册了四种桥接模式;假设您可以实现自己的桥接模式,您仍然需要将其注册为NativetoJSMessageQueue的新模式。

答案 2 :(得分:2)

我不确定你想要做什么,但我注意到你在项目中将JSON转换为String然后你将它传递给PhoneGap插件,将其转换为JSON然后将其转换为Matrix!

如果您将数据保存在字符串中并将字符串直接转换为Matrix,该怎么办? 通过这种方式,您可以跳过与JSON部分的转换

答案 3 :(得分:2)

在android上,您可以尝试使用addJavascriptInterface的{​​{1}}(link to WebView's documentation)方法“将Java对象注入WebView”,这是PhoneGap用来添加的方法地理定位,文件系统等的api

我想这会比使用插件方法更快(暂不测试)。

检查扩展WebView的{​​{1}}的代码: https://github.com/phonegap/phonegap/blob/3c7324ea8b3944b6e5d3d91e9e328c9c3939464b/android/framework/src/com/phonegap/PhoneGapView.java#L42

<强>更新

毕竟,这仅适用于PhoneGapViewWebView等简单类型,就像您在下面的评论中所说的那样。

Passing a JavaScript object using addJavascriptInterface() on Android

如果不这样做,将导致intString类内的例外情况。

更新2

嗯,使用这种方法你将获得的最佳代码将是这样的 (来自https://github.com/commonsguy/cw-advandroid/blob/master/WebView/GeoWeb1/src/com/commonsware/android/geoweb/GeoWebOne.java#L80):

android.webkit.WebViewCore

并且很可能,所有参数都应该是字符串'(或JSON'fied ...)

如果您在尝试从javascript端创建字符串时遇到性能影响,这可能会有所帮助:http://www.javascripture.com/ArrayBuffer

答案 4 :(得分:1)

我读过有关在png中编码数据的内容。以下是原始文章:http://cg.alexandra.dk/2012/11/26/webgl-tutorial-optimizing-data-transfer-for-webgl-applications/

可能有用。

答案 5 :(得分:1)

鉴于json的效率非常低,如果采用这种方法,你可能会获得很多性能:

服务器端: 数据模型 - &gt; protobuf(build()到binary) - &gt;编码base64(二进制到字符串) - &gt;添加为一个json字段或有效负载(最好是将二进制blob作为有效负载传递,但我不确定PhoneGap是否允许这样做)

客户端: 从base64解码(字符串到二进制) - &gt; protobuf(从二进制解析) - &gt;在代码中尽可能深地使用protobuf对象 - 这是非常有效的数据模型