Подтвердить что ты не робот

Плагин 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 в native, что позволяет избежать этого. В идеале это должно работать как на Android, так и на iOS, но я счастлив придерживаться только Android-решения. Есть ли у кого-нибудь идеи относительно наиболее эффективного способа сделать это?

4b9b3361

Ответ 1

Linkedin использует веб-сокеты для своего iPad-приложения. Можно подумать: http://engineering.linkedin.com/mobile/linkedin-ipad-nativeweb-messaging-bridge-and-websockets

Некоторые преимущества, которые вы ищете

  • WebSockets может связываться асинхронно с JavaScript на native.
  • У WebSockets нет предела полезной нагрузки
  • WebSockets не требуют, чтобы мы кодировали наши строки JSON в качестве параметров URL
  • WebSockets должен быть быстрее навигации по схеме URL.

Ответ 2

Производительность адресации

Глядя на CordovaPlugin.java, все, что вы упомянули, - это String:

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

Если, например, преобразование с String в JSONArray является единственным узким местом, вы можете переопределить этот метод в своем плагине и выполнить свою десериализацию. Это небольшое улучшение производительности, но, возможно, стоит изучить.

Создание альтернативного моста

Что касается создания альтернативного моста, это сложнее. Я не знаю много о Cordova/PhoneGap, но из каких исследований я собрал Кордова предоставляет конкретный интерфейс Javascript через addJavascriptInterface. Если вы можете реализовать свой собственный NativetoJSMessageQueue, вы можете связать все это вместе.

ИЗМЕНИТЬ
Проведя немного больше исследований, я могу дать немного больше направлений. На самом деле актуальная часть NativetoJSMessageQueue представляет собой различные BridgeModes, которые она реализует (см. line 92). В качестве примера вы можете посмотреть другие режимы моста.

К сожалению, NativetoJSMessageQueue имеет ровно четыре зарегистрированных режима моста; предполагая, что вы можете реализовать свой собственный режим моста, вам все равно нужно каким-то образом зарегистрировать его как новый режим для NativetoJSMessageQueue.

Ответ 3

Я не уверен, что именно вы хотите сделать, но я заметил, что в вашем проекте вы конвертируете JSON в String, а затем передаете его через плагин PhoneGap, конвертируете его в JSON, а затем конвертируете в Matrix!

что, если вы сохраните свои данные в строке и преобразуете строку прямо в матрицу? таким образом вы можете пропустить преобразование в часть JSON и из нее

Ответ 4

В андроиде вы можете попробовать использовать addJavascriptInterface (ссылка на документацию WebView) метод WebView to "ввести Java-объекты в WebView", который является подходом, который использует PhoneGap для добавления apis для геолокации, файловой системы и т.д.

Я предполагаю, что это будет быстрее, чем использование подхода плагина (еще не проверили это).

Проверьте код PhoneGapView, который расширяет WebView: https://github.com/phonegap/phonegap/blob/3c7324ea8b3944b6e5d3d91e9e328c9c3939464b/android/framework/src/com/phonegap/PhoneGapView.java#L42

UPDATE

В конце концов, это работает только для простых типов, таких как int или String, как вы сказали в комментарии ниже.

Передача объекта JavaScript с помощью addJavascriptInterface() на Android

Попытка сделать иначе приведет к исключениям из классов android.webkit.WebViewCore и android.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...)

Это может помочь вам, если у вас есть производительность, когда triying создает строки со стороны javascript: http://www.javascripture.com/ArrayBuffer

Ответ 6

Учитывая, что json очень неэффективен, вы можете получить большую производительность, если вы выполните этот маршрут:

сторона сервера: data model → protobuf (build() to binary) → encode base64 (двоичный код для строки) → добавить как одно поле json или полезную нагрузку (лучше всего передать бинарный блок как полезную нагрузку, но я не уверен, что PhoneGap разрешает это)

клиентская сторона: декодировать из base64 (строка в двоичный) → protobuf (проанализировать из двоичного) → использовать объекты protobuf как можно глубже, чем вы можете в своем коде - это чрезвычайно эффективная модель данных