在Android上使用MessagePack

有人试图用Android应用程序使用MessagePack
可能吗? 我试图从msgpack-java使用Jar并收到以下exception:

 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 

我使用的代码非常简单

 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(); 

我有我的lib目录中的javassist.jarmsgpack-0.5.2.jarslf4j-api-1.6.2.jarslf4j-jdk14-1.6.2.jar

在我的服务器应用程序中,这个代码可以和相同的库一起工

Solutions Collecting From Web of "在Android上使用MessagePack"

(希望)最终更新

msgpack0.6.8在Android上运行没有任何问题

msgpack-rpc0.7.0在Android上有一个警告。

具体而言,您需要将以下内容添加到API Level 8(Android 2.2.1)的onCreate中,并可能更低:

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

由于这个错误 。

如果你想看一个简单的例子,这里有一对为此设置的项目:


之前的版本

更新:从0.6.7 msgpack应与Android兼容 (有一个小的依赖排除问题)。 检查下面的文本msgpack-rpc(这也可能在未来适应)。

注意:如果您还使用msgpack-rpc ,则需要执行以下步骤:

  1. git://github.com/msgpack/msgpack-rpc.git (特别是“java”文件夹 )下载msgpack-rpc源文件
  2. 将主msgpack工件版本更改为您创build的版本。
  3. org.msgpack.rpc.loop.netty.NettyEventLoop中 ,将NioClientSocketChannelFactory更改为OioClientSocketChannelFactory(getWorkerExecutor())
  4. 按照与主要MessagePack JAR相同的方式构buildMessagePack-RPC(请参阅上面的步骤11 )。

NettyEventLoop更换是由于这个问题: http : //markmail.org/message/ypa3nrr64kzsyfsa

重要说明:我只testing了同步通信。 asynchronous可能不起作用。


这是msgpack在0.6.7之前不能与Android一起工作的原因:

错误的原因是MessagePack使用了几个不包含在Android SDK中的java.beans类。 你可能使用了MessagePackBeans注解。

这是一个类似的问题, 这里描述的一般解决scheme在这里概述。 不幸的是,在我们的情况下,它需要重buildmsgpack。 这就是我所做的(几乎可以肯定跳过第5步和第8步,但是我没有尝试过):

  1. https://github.com/msgpack/msgpack-java.git下载MessagePack源代码。
  2. 在您的IDE中将MessagePack源导入为一个项目。
  3. http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java下载相关软件包的Apache Harmony源代码。
  4. 将这些包复制到MessagePack项目的src / main / java文件夹中:
    • java.beans中
    • java.beans.beancontext中
    • org.apache.harmony.beans
    • org.apache.harmony.beans.internal.nls
  5. 在您的MessagePack项目中,删除以下类:
    • 的PropertyChangeListener
    • IndexedPropertyChangeEvent
    • 的PropertyChangeEvent
    • PropertyChangeListenerProxy
    • 的PropertyChangeSupport
  6. java.beans包重命名为不同的内容,例如custom.beans
  7. 所有 java.beans引用更改为重命名的ID,例如custom.beans 。 这特别适用于BeansFieldEntryReader (这个类是原始错误的原因)。
  8. 将您在第5步中删除的五个类的custom.beans引用更改回java.beans
  9. org.apache.harmony.beans.internal.nls.Messages类中,注释掉setLocale方法,并删除与之关联的导入。
  10. 编码器 ,删除所有仍然有错误的类。 在那个类中,注释掉所有你已经删除的类的引用。 你现在应该有一个没有错误的项目。
  11. 构buildMessagePack JAR:
    • 如果您使用的是Maven,请将pom.xml中的版本更改为独特的版本,使用安装目标运行Maven build,然后在您的Android项目中添加该版本的依赖项。
    • 如果你使用Maven,你必须使用包含的build.xml来运行Ant的jar目标。 用这个replaceAndroid项目中的msgpack JAR。
  12. 如果您要发布您的应用程序,请记住包含Apache Harmony的相关法律声明。 这是一个Apache许可证,就像MessagePack一样。

这应该做到这一点。 使用您的示例代码和我自己的数据类,我成功地打包和解包数据。

整个重命名仪式是由于DEX编译器抱怨java。*包的命名。

有一个关键的msgpack错误,说与msgpack打包数据将损坏Dalvik虚拟机。 http://jira.msgpack.org/browse/MSGPACK-51

@TheTerribleSwiftTomato和MessagePack核心团队正在不断努力让MessagePack在Android上工作,请参阅相关的GitHub问题 。 在TheTerribleSwiftTomato的答案中提到的修复方法可以在这里find。

更新

我已经设法让它至less在Android上运行(辛苦地)添加所有必要的javassist类,目前需要的构build才能成功。 一个额外的600KB的大小增加,但至less它似乎工作。 总而言之,Android在某种程度上似乎正在工作,最终检查出有关消息包(如用户组及其维基)的鲜为人知的资源以获取更多信息。

请注意,请确保使用可处理二进制数据的HTTP请求库(如LoopJ的AndroidasynchronousHTTP或Apache的HttpClient )。

最后但并非最不重要的,你可以ping我,如果有兴趣在这个jar ,使得MessagePack看起来在Android上工作 – 学分当然是@TheTerribleSwiftTomato谁提供上述修复!

我build议你在主要的proguard-rules文件中写这个 –

 -dontwarn org.msgpack.** -keep class org.msgpack.** { *; }