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

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

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

Solutions Collecting From Web of "PhoneGap插件:将JSON数据传输到本机的最快方法"

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

您正在寻找的一些好处

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

解决性能问题

正如你所提到的,看看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通过addJavascriptInterface 公开了一个特定的Javascript界面 。 如果您可以实现自己的NativetoJSMessageQueue ,那么您可以将它们连接在一起。

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

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

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

如果您将数据保存在字符串中并将字符串直接转换为Matrix怎么办? 这样你就可以跳过JSON部分的转换

在android上,您可以尝试使用WebView的 addJavascriptInterface ( 链接到WebView的文档 )方法“将Java对象注入WebView”,这是PhoneGap用于为地理位置,文件系统等添加api的方法。

我想这会比使用插件方法更快(还没有测试过)。

检查PhoneGapView的代码,它扩展了WebView : https : //github.com/phonegap/phonegap/blob/3c7324ea8b3944b6e5d3d91e9e328c9c3939464b/android/framework/src/com/phonegap/PhoneGapView.java#L42

UPDATE

毕竟,这只适用于简单types,如intString ,就像你在下面的评论中所说的那样。

在Android上使用addJavascriptInterface()传递JavaScript对象

尝试不这样做会导致android.webkit.WebViewCoreandroid.webkit.JWebCoreJavaBridge类中的exception。

更新2

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

 public String getLocation() throws JSONException { Location loc=myLocationManager.getLastKnownLocation(PROVIDER); if (loc==null) { return(null); } JSONObject json=new JSONObject(); json.put("lat", loc.getLatitude()); json.put("lon", loc.getLongitude()); return(json.toString()); } 

而且最有可能的是,所有参数都应该是字符串’(或JSON’fied …)

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

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

可能有用。

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

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

客户端:从base64解码(字符串到二进制) – > protobuf(从二进制解析) – >直接使用protobuf对象尽可能深入你的代码 – 这是非常有效的数据模型