Uso de MessagePack con Android

¿Alguien ha intentado usar MessagePack con una aplicación para Android?
¿Es posible? He intentado utilizar el msgpack-java de msgpack-java y recibido la excepción siguiente:

 Caused by: java.lang.ExceptionInInitializerError at org.msgpack.Packer.pack(Packer.java:532) at org.msgpack.MessagePack.pack(MessagePack.java:31) ... 15 more Caused by: java.lang.ExceptionInInitializerError at org.msgpack.template.TemplateRegistry.<clinit>(TemplateRegistry.java:38) ... 17 more Caused by: java.lang.VerifyError: org.msgpack.template.BeansFieldEntryReader at org.msgpack.template.builder.BeansTemplateBuilder.<init (BeansTemplateBuilder.java:42) at org.msgpack.template.builder.BuilderSelectorRegistry.initForJava(BuilderSelectorRegistry.java:73) at org.msgpack.template.builder.BuilderSelectorRegistry.<clinit>(BuilderSelectorRegistry.java:38) ... 18 more 

El código que utilizo es muy simple

 PrintWriter out = new PrintWriter(socket.getOutputStream()); Message msg = new Message(); msg.body = "asdasdasd"; msg.from = "qwe"; msg.to = "ttt"; byte[] bytes = MessagePack.pack(msg); out.print(bytes); out.flush(); 

Tengo javassist.jar , msgpack-0.5.2.jar , slf4j-api-1.6.2.jar y slf4j-jdk14-1.6.2.jar en mi directorio de lib .

En mi aplicación de servidor este código funciona bien con las mismas bibliotecas.

(Esperanzadamente) ACTUALIZACIÓN FINAL

Msgpack : 0.6.8 funciona en Android sin ningún problema

Msgpack-rpc : 0.7.0 funciona en Android con una advertencia.

Específicamente, debe agregar lo siguiente a onCreate para API Level 8 (Android 2.2.1), y posiblemente menor:

 java.lang.System.setProperty("java.net.preferIPv4Stack", "true"); java.lang.System.setProperty("java.net.preferIPv6Addresses", "false"); 

Debido a este error .

Si desea ver un ejemplo simple, aquí hay un par de proyectos creados para este propósito:


Versión anterior

UPDATE: a partir de 0.6.7 msgpack debería ser compatible con Android (hay un pequeño problema de exclusión de dependencia). Compruebe el texto siguiente para msgpack-rpc (que también podría ser adaptado en el futuro).

NOTA: Si también utiliza msgpack-rpc , debe realizar los siguientes pasos:

  1. Descargue la fuente msgpack-rpc desde git: //github.com/msgpack/msgpack-rpc.git (específicamente, la carpeta "java" ).
  2. Cambia la versión principal del artefacto de msgpack a la que has construido.
  3. En org.msgpack.rpc.loop.netty.NettyEventLoop , cambie NioClientSocketChannelFactory a OioClientSocketChannelFactory (getWorkerExecutor ()) .
  4. Construya el MessagePack-RPC de la misma manera que en el caso del MessagePack JAR principal (vea el Paso 11 ).

El reemplazo NettyEventLoop se debe a este problema: http://markmail.org/message/ypa3nrr64kzsyfsa .

Importante: Solo he probado la comunicación sincrónica . Asíncrono podría no funcionar.


Y aquí está la razón de que msgpack no funciona con Android antes de 0.6.7 :

La razón del error es que MessagePack utiliza varias clases de java.beans que no se incluyen en el SDK de Android. Probablemente utilice la anotación de MessagePackBeans .

Este es un problema similar al descrito aquí , para el cual la solución general se describe aquí . Desafortunadamente, en nuestro caso requiere una reconstrucción de msgpack. Esto es lo que hice (casi con seguridad puede saltarse los pasos 5 y 8, pero no lo he probado de esa manera):

  1. Descargue la fuente de MessagePack desde https://github.com/msgpack/msgpack-java.git .
  2. Importe el origen MessagePack como un proyecto en su IDE.
  3. Descargue la fuente de Apache Harmony para los paquetes correspondientes de http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java .
  4. Copie estos paquetes en la carpeta src / main / java de su proyecto MessagePack:
    • Java.beans
    • Java.beans.beancontext
    • Org.apache.harmony.beans
    • Org.apache.harmony.beans.internal.nls
  5. En su proyecto MessagePack, quite las clases siguientes:
    • PropertyChangeListener
    • IndexedPropertyChangeEvent
    • PropertyChangeEvent
    • PropertyChangeListenerProxy
    • PropertyChangeSupport
  6. Cambie el nombre de los paquetes java.beans a algo diferente, por ejemplo, custom.beans .
  7. Cambie todas las referencias de java.beans al ID renombrado, por ejemplo, por ejemplo, custom.beans . Esto se aplica especialmente a BeansFieldEntryReader (esta clase es la razón del error original).
  8. Cambie las referencias custom.beans de las cinco clases que quitó en el Paso 5 de nuevo a java.beans .
  9. En la clase org.apache.harmony.beans.internal.nls.Messages , comente el método setLocale y elimine las importaciones asociadas a él.
  10. Quite todas las clases que aún tienen errores, excepto Encoder . En esa clase, comente todas las referencias a las clases que ha eliminado. Ahora debe tener un proyecto sin errores.
  11. Construir el JAR MessagePack:
    • Si está utilizando Maven, cambie la versión en el pom.xml a algo único, ejecute Maven con el objetivo de instalación y , a continuación, agregue la dependencia en su proyecto de Android con esa versión .
    • Si no está usando Maven, tiene que ejecutar el objetivo jar para Ant con el build.xml incluido. Reemplace el JAR de msgpack en su proyecto de Android con éste.
  12. Si publicas tu aplicación, recuerda incluir el aviso legal relevante para Apache Harmony. Es una licencia de Apache, al igual que MessagePack.

Deberias hacer eso. Utilizando su código de ejemplo y mi propia clase de datos, tuve éxito en la tarea de empaquetar y descomprimir datos.

Todo el ritual de cambio de nombre se debe al hecho de que el compilador DEX se queja de java. * Nombre de paquete.

Hay un error crítico de msgpack diciendo que los datos empacados con msgpack se dañarán en la VM de Dalvik. http://jira.msgpack.org/browse/MSGPACK-51

Hay un esfuerzo continuo por @TheTerribleSwiftTomato y el equipo principal de MessagePack para que MessagePack trabaje en Android, por favor vea el problema relacionado con GitHub . La solución mencionada en la respuesta de @ TheTerribleSwiftTomato se encuentra aquí .

Actualizar

He logrado que al menos se ejecute en Android por (penosamente) la adición de todas las clases necesarias javassist que actualmente se requieren para la construcción para tener éxito. Una ganancia extra de 600KB en tamaño, pero al menos parece funcionar. En definitiva, parece estar funcionando hasta cierto punto en Android, con el tiempo revisar los recursos menos conocidos sobre Message Pack, como su grupo de usuarios y su Wiki para obtener más información.

En una nota lateral, asegúrese de utilizar una biblioteca de solicitudes HTTP (como el HTTP Async de Android de LoopJ o el HttpClient de Apache) que puede manejar datos binarios .

Por último, pero no menos importante, puede hacer ping si hay interés en este jar que hace que MessagePack aparentemente funcione en Android – los créditos salen por supuesto a @TheTerribleSwiftTomato que proporcionó la solución anterior!

Le sugiero que escriba esto en el archivo proguard-rules principal-

 -dontwarn org.msgpack.** -keep class org.msgpack.** { *; } 
  • Autofocus de la cámara Android cuando el usuario mantiene la cámara inmóvil
  • Métodos para dar la mejor estimación de ubicación de tres proveedores de ubicación de Android
  • Publicar un tweet con la API de Android
  • Hace tiempo para Android / java
  • Cómo saber si un dispositivo Android está cerca de una dirección google maps api
  • NullPointerException al llamar a la clase auto-escrita
  • ¿Debo usar estática o getters / setters?
  • Cómo obtener los archivos de la ruta correcta en android
  • Android - reproducir sonido diferente en cada segundo clic
  • ¿Una clase anónima mantiene referencias externas vivas?
  • Biblioteca de Android xmpp
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.