【问题标题】:PhoneGap plugin: fastest way to transfer JSON data to nativePhoneGap 插件:将 JSON 数据传输到本机的最快方法
【发布时间】:2012-11-07 17:50:58
【问题描述】:

我一直在开发一个启用 WebGL 的 PhoneGap 插件,旨在将 HTML5 游戏发布到移动设备上。它被称为WebGLGap。但是,PhoneGap 调用插件代码的方式(通过 exec)通常涉及将所有参数字符串化为 JSON,然后在另一端再次对其进行解析。根据this question 的说法,即使在PhoneGap 2.2 中也没有改变,它被宣传为具有更快的网桥。对于像 WebGL 这样的东西,这绝对是站不住脚的,即使是简单的演示也会降低性能(

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

【问题讨论】:

  • 您在寻找实用的解决方案吗?我想试一试,但今天我可能做不到,只有明天......
  • “实用”,如,工作代码:)
  • 只有一个建议,想知道有没有办法在webql、js这两者之间建立一个websocket连接到natvie app。
  • 您是否考虑过将数据包装在 json-p 回调函数中?

标签: javascript android cordova phonegap-plugins


【解决方案1】:

解决性能问题

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 interface 通过addJavascriptInterface。如果您可以实现自己的NativetoJSMessageQueue,则可以将它们连接在一起。

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

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

【讨论】:

  • 谢谢,但我认为即使是通过转换为字符串的自定义方式也可能太慢......除非有一种快速的方式来共享一个像二进制缓冲区这样的字符串?不过,创建替代桥梁听起来很有希望......
【解决方案2】:

我不确定您到底想做什么,但我注意到在您的项目中您将 JSON 转换为 String,然后您将通过 PhoneGap 插件将其传递,将其转换为 JSON,然后将其转换为 Matrix!

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

【讨论】:

  • 谢谢,但矩阵不是项目的性能敏感部分,主要是缓冲区数据数组。我需要一种完全避免字符串化的方法。
【解决方案3】:

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

您正在寻找的一些好处

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

【讨论】:

  • 对 iOS 来说非常有前途,但在 Android 上仍然完全不受支持(至少在股票浏览器中,你基本上可以通过 PhoneGap 获得)。 Android 的任何替代想法?
  • PhoneGap 是否支持网络套接字?
  • @NT3RP 问题更多:Safari 或 Android 股票浏览器是否支持 Web 套接字。不幸的是,Android 股票似乎没有。
  • 这看起来是适用于 iOS 的最佳解决方案 - 不幸的是,它看起来不适用于 Android,但希望 Google 尽快采取行动并用 Chrome(完整的 WebSockets)取代现有的浏览器...恭喜,你赢得了赏金!
【解决方案4】:

在android上,你可以尝试使用WebViewaddJavascriptInterfacelink to WebView's documentation)方法“将Java对象注入WebView”,这是PhoneGap用来添加地理定位、文件系统的api的方法等。

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

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

更新

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

Passing a JavaScript object using addJavascriptInterface() on Android

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

更新 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());
}

而且最有可能的是,所有参数都应该是 string'fied(或 JSON'fied...)

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

【讨论】:

  • 谢谢,听起来很有希望,但根据这里:blog.johnmckerrell.com/2011/01/21/… “经过一些测试,我发现 addJavascriptInterface 只允许基本数据类型,例如布尔、整数和字符串。”然后他们继续描述一种解决方法......涉及字符串化。我至少需要传递一组浮点数 - addJavascriptInterface 支持吗?
  • 如果你想要异步回调,我猜你有麻烦了 (github.com/phonegap/phonegap/blob/…);我会尝试查看Java方法的同步调用
  • 这是一个很好的发现,但恐怕字符串化 JSON 正是我需要避免的......它确实会降低性能!
  • 我开始觉得你要么必须 1) 将 html+js 编译为本机应用程序(想法不断增长,同时可能会开始概念验证)或 2) 改进android.webkit.* 类
【解决方案5】:

我已经阅读了有关在 png 中编码数据的信息。以下为文章原文:http://cg.alexandra.dk/2012/11/26/webgl-tutorial-optimizing-data-transfer-for-webgl-applications/

可能有用。

【讨论】:

  • 抱歉,看起来它更多的是用于缓存而不是将数据传输到 PhoneGap 插件。
【解决方案6】:

鉴于 json 效率非常低,如果你走这条路线,你可能会获得很多性能:

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

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

【讨论】:

    猜你喜欢
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    相关资源
    最近更新 更多