12

有人尝试过使用MessagePackAndroid 应用程序吗?
可能吗?我尝试使用 Jarmsgpack-java并收到以下异常:

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.jar和。 slf4j-api-1.6.2.jarslf4j-jdk14-1.6.2.jarlib

在我的服务器应用程序中,此代码适用于相同的库。

4

4 回答 4

14

(希望)最终更新

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

msgpack-rpc0.7.0在 Android 上工作,但有一点需要注意。

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

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 工件版本更改为您已构建的版本。
  3. org.msgpack.rpc.loop.netty.NettyEventLoop中,将NioClientSocketChannelFactory更改为OioClientSocketChannelFactory(getWorkerExecutor())
  4. 以与主 MessagePack JAR 相同的方式构建 MessagePack-RPC(参见上面的步骤 11)。

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

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


这就是 msgpack 之前无法与 Android 一起使用的原因0.6.7

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

这是与此处描述的问题类似的问题,此处概述了通用解决方案。不幸的是,在我们的例子中,它需要重新构建 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.bean上下文
    • org.apache.harmony.beans
    • org.apache.harmony.beans.internal.nls
  5. 在您的 MessagePack 项目中,删除以下类:
    • 属性更改监听器
    • IndexedPropertyChangeEvent
    • 属性更改事件
    • PropertyChangeListenerProxy
    • 属性更改支持
  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 一样。

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

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

于 2011-10-02T01:40:58.130 回答
0

@TheTerribleSwiftTomato 和 MessagePack 核心团队一直在努力让 MessagePack 在 Android 上运行,请参阅相关的GitHub 问题。@TheTerribleSwiftTomato 的答案中提到的修复可以在这里找到。

更新

javassist通过(煞费苦心地)添加当前构建成功所需的所有必要类,我已经设法让它至少在 Android 上运行。尺寸上的额外600KB增加,但至少它似乎有效。总而言之,它似乎在某种程度上适用于 Android,最终查看关于 Message Pack 的鲜为人知的资源,例如其用户组和它的Wiki,以获取更多信息。

附带说明一下,一定要使用可以处理二进制数据的 HTTP 请求库(例如 LoopJ 的Android Async HTTP或 Apache 的HttpClient ) 。

最后但并非最不重要的一点是,如果您对此感兴趣,这jar使 MessagePack 似乎可以在 Android 上运行,您可以联系我 - 当然,感谢 @TheTerribleSwiftTomato 提供了上述修复!

于 2012-08-15T06:43:57.377 回答
0

有一个严重的 msgpack 错误说使用 msgpack 打包的数据将在 Dalvik VM 上损坏。http://jira.msgpack.org/browse/MSGPACK-51

于 2011-10-31T22:06:47.510 回答
0

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

-dontwarn org.msgpack.**
-keep class org.msgpack.** { *; }
于 2017-05-10T07:22:18.170 回答