在Android上使用MessagePack

时间:2011-09-23 13:14:59

标签: java android msgpack messagepack

有人试图将MessagePack与Android应用一起使用吗? 可能吗?我试图使用来自msgpack-java的Jar并收到以下异常:

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

我的javassist.jar目录中有msgpack-0.5.2.jarslf4j-api-1.6.2.jarslf4j-jdk14-1.6.2.jarlib

在我的服务器应用程序中,此代码可以在相同的库中正常工作。

4 个答案:

答案 0 :(得分:13)

(希望)最终更新

msgpack 0.6.8在Android上运行没有任何问题

msgpack-rpc 0.7.0适用于Android,但有一点需要注意。

具体来说,您需要将以下内容添加到API级别8(Android 2.2.1)的onCreate,并可能更低:

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

归因于this bug

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


以前的版本

更新:截至0.6.7 msgpack should be compatible with Android(存在小的依赖项排除问题)。请查看下面的文本,了解msgpack-rpc(以后也可能会对其进行调整)。

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

  1. git://github.com/msgpack/msgpack-rpc.git 下载msgpack-rpc源代码(具体来说,&#34; java&#34;文件夹)。
  2. 将主要的msgpack工件版本更改为您已构建的版本。
  3. org.msgpack.rpc.loop.netty.NettyEventLoop 中,将 NioClientSocketChannelFactory 更改为 OioClientSocketChannelFactory(getWorkerExecutor())
  4. 以与主MessagePack JAR相同的方式构建MessagePack-RPC(参见上面的步骤11 )。
  5. NettyEventLoop 替换是由于此问题: http://markmail.org/message/ypa3nrr64kzsyfsa

    重要提示:我只测试了同步通讯。异步可能不起作用。


    以下是0.6.7之前msgpack无法使用Android的原因:

    错误的原因是MessagePack使用了几个未包含在Android SDK中的java.beans类。您可能正在使用 MessagePackBeans 注释。

    这与描述here的问题类似,为此概述了一般解决方案here。不幸的是,在我们的例子中,它需要重建msgpack。这就是我所做的(你几乎可以肯定地跳过第5步和第8步,但我还没有尝试过这种方式):

    1. https://github.com/msgpack/msgpack-java.git 下载MessagePack来源。
    2. 将MessagePack源作为项目导入IDE。
    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. 删除所有仍有错误的类 Encoder 。在该课程中,注释掉您已删除的课程的所有引用。你现在应该有一个没有错误的项目。
    11. 构建MessagePack JAR:
      • 如果您正在使用Maven,请将pom.xml中的版本更改为唯一的版本,使用 install 目标运行Maven构建,然后在Android项目中添加依赖项使用该版本
      • 如果您使用Maven ,则必须使用随附的 build.xml 运行Ant的 jar 目标。用这个替换你的Android项目中的msgpack JAR。
    12. 如果您要发布自己的应用,请记住包含Apache Harmony的相关法律声明。它就是Apache许可证,就像MessagePack一样。
    13. 应该这样做。使用您的示例代码和我自己的数据类,我成功地能够打包和解压缩数据。

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

答案 1 :(得分:0)

有一个关键的msgpack错误,说用msgpack打包的数据在Dalvik VM上会被破坏。 http://jira.msgpack.org/browse/MSGPACK-51

答案 2 :(得分:0)

@TheTerribleSwiftTomato和MessagePack核心团队正在努力让MessagePack在Android上运行,请参阅相关的GitHub issue。在@TheTerribleSwiftTomato的答案中提到的修复程序是here

<强>更新

我已经设法让它至少在Android上运行(辛苦地)添加了当前构建成功所需的所有必需的javassist类。大小增加600KB,但至少似乎有效。总而言之,它似乎在某种程度上在Android上工作,最终查看有关Message Pack的鲜为人知的资源,例如User Group及其Wiki以获取更多信息。

另一方面,请务必使用可以处理二进制数据的HTTP请求库(例如LoopJ的Android Async HTTP或Apache的HttpClient)。

最后但并非最不重要的是,如果对此jar感兴趣使得MessagePack似乎在Android上运行,那么你可以打电话给我 - 积分当然是@TheTerribleSwiftTomato提供上述修复程序!

答案 3 :(得分:0)

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

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