为Intel® x86平台上的Android应用程序编译ZeroMQ库





0/5 (0投票)
分步构建ZeroMQ库的x86版本
Intel® Developer Zone 提供跨平台应用程序开发工具和操作指南、平台和技术信息、代码示例以及同行专业知识,以帮助开发人员进行创新并取得成功。加入我们的社区,了解 Android、物联网、Intel® RealSense™ 技术 和 Windows,下载工具、访问开发套件、与志同道合的开发人员分享想法,并参与黑客松、竞赛、路演和本地活动。
引言
ZeroMQ 是一个被世界各地程序员广泛使用的开源库。其维基百科定义如下:“ZeroMQ (也拼写为 ØMQ, 0MQ 或 ZMQ) 是一个高性能的异步消息传递库,旨在用于可扩展的分布式或并发应用程序。它提供消息队列,但与面向消息的中间件不同,ZeroMQ 系统可以在没有专用消息代理的情况下运行。该库设计为具有熟悉的套接字风格 API。”
在 ZeroMQ 的网站上,社区已经提供了 Android 平台的构建说明(https://zeromq.cn/build:android)。然而,这些说明主要针对 ARM* 架构,开发人员在按照说明一步步构建 ZeroMQ 库的 x86 版本时会遇到构建失败。这就是本文的撰写原因。
构建环境准备
构建 ZeroMQ 的第一个目标是为 x86 创建一个独立于其他环境的专用工具链,该工具链依赖于 Android NDK。
- 从以下地址下载并安装最新的 Android NDK:
https://developer.android.com.cn/tools/sdk/ndk/index.html。本文我们使用 android-ndk-r10d-linux-x86_64。 - 通过应用 https://code.google.com/p/android/issues/detail?id=74145 中提到的补丁,修复 make-standalone-toolchain.sh 中的一个已知问题。没有这个补丁,下一步的构建将会失败。
- 为 Android x86 平台生成独立的工具链。
./home/xxx/android-ndk-r10c/build/tools/make-standalone-toolchain.sh --arch=x86 --toolchain=x86-4.9 --install-dir=/home/xxx/android-standalone-toolchain-x86
您应该遵循接下来的两个建议,以避免意外的构建问题:- 在单独的目录中生成一个 x86 工具链。不要将 x86 工具链和 ARM 工具链混入同一个目录。
- 将独立的工具链安装在您的 /home 目录下,以帮助避免 root/no-root 权限问题。
- 配置环境变量。
export PATH=/home/xxx/android-standalone-toolchain-x86/bin:$PATH export OUTPUT_DIR=/home/xxx/tmp/zeromq-android
构建适用于 Android x86 的 ZeroMQ
以下步骤将向您展示如何构建 ZeroMQ 以及 Jzmq 及其配套的 JAR 文件,以便可以直接在 Android 中使用并加载到 APK 文件中。
- 下载源代码并构建 ZeroMQ 3.x。
mkdir /home/xxx/tmp cd /home/xxx/tmp git clone https://github.com/zeromq/zeromq3-x.git cd zeromq3-x/ ./autogen.sh ./configure --host=i686-linux-android --prefix=$OUTPUT_DIR LDFLAGS="-L$OUTPUT_DIR/lib" CPPFLAGS="-fPIC -I$OUTPUT_DIR/include" --enable-static --disable-shared LIBS="-lgcc" make make install
- 下载源代码并构建 jzmq。
cd /home/xxx/tmp git clone https://github.com/zeromq/jzmq.git cd jzmq/ ./autogen.sh ./configure --host=i686-linux-android --prefix=$OUTPUT_DIR LDFLAGS="-L$OUTPUT_DIR/lib" CPPFLAGS="-fPIC -I$OUTPUT_DIR/include" --disable-version --with-zeromq=$OUTPUT_DIR LIBS="-lpthread -lrt" make make install
如果在执行 "./configure" 时出现失败,请移除 LIBS="-lpthread –lrt" 并重试。 - 将 libjzmq.so 和 zmq.jar 文件复制到您所需的目录,现在 ZeroMQ 已经成功构建!
cp /home/xxx/tmp/zeromq-android/lib/libjzmq.so /home/xx/tmp/ cp /home/xxx/tmp/zeromq-android/share/java/zmq.jar /home/xx/tmp/
在 Android x86 中使用 ZeroMQ 的示例
您现在可以在 Android 应用程序中使用 ZeroMQ 了。这里有一个简单的分步示例,描述了如何在 ZeroMQ 客户端和 ZeroMQ 服务器之间实现消息交互。部分示例代码来自 ZeroMQ 官方指南,并封装到 Android 项目中。
- 将 libjzmq.so 复制到 "DemoJZMQ/jni/" 目录,并将 zmq.jar 复制到 "DemoJZMQ/libs/" 目录。
- 将以下脚本添加到 Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libjzmq LOCAL_SRC_FILES := libjzmq.so include $(PREBUILT_SHARED_LIBRARY)
- 将以下脚本添加到 Application.mk。
APP_ABI := x86
- 实现服务器端功能。
public void startZMQserver() throws Exception { ZMQ.Context context = ZMQ.context(1); // Socket to talk to clients responder = context.socket(ZMQ.REP); responder.bind("tcp://*:" + SERVER_PORT); printLog("Server", "Started"); while (!Thread.currentThread().isInterrupted()) { // Wait for next request from the client byte[] request = responder.recv(0); printLog("Server", "Received:" + new String(request)); // Do some 'work' Thread.sleep(1000); // Send reply back to client String reply = "World"; responder.send(reply.getBytes(), 0); printLog("Server", "Response send."); } responder.close(); context.term(); }
- 实现客户端功能。
public void startZMQclient() throws Exception { ZMQ.Context context = ZMQ.context(1); // Socket to talk to server printLog("Client", "Connecting to ZMQ server…"); requester = context.socket(ZMQ.REQ); requester.connect("tcp://" + SERVER_IP + ":" + SERVER_PORT); printLog("Client", "Connected to server."); for (int requestNbr = 0; requestNbr != 10; requestNbr++) { String request = "Hello"; printLog("Client", "Sending Hello " + requestNbr); requester.send(request.getBytes(), 0); byte[] reply = requester.recv(0); printLog("Client", "Received " + new String(reply) + " " + requestNbr); } requester.close(); context.term(); }
- 在设备上运行示例应用程序,先点击“start server”按钮,然后点击“start client”。从“adb logcat”可以看到执行结果(图 1),显示当客户端向服务器发送“Hello”时,服务器向客户端返回“World”10 次。
图 1. Demo JZMQ 启动屏幕及日志文件示例。
摘要
本文分步介绍了如何为 Android x86 平台编译 ZeroMQ 库。还提供了一个简单的消息传输示例,展示了如何在 Android 应用程序中使用 ZeroMQ。如前所述,成功编译适用于 x86 的 ZeroMQ 的关键在于基于 Android NDK 为 x86 生成正确的独立工具链。此方法不仅对 ZeroMQ 有用,对其他第三方库的构建也有帮助。
参考文献
- ØMQ - http://en.wikipedia.org/wiki/%C3%98MQ
- ZeroMQ for Android builds - https://zeromq.cn/build:android
- ØMQ - The Guide - https://zguide.zeromq.cn/page:all
关于作者
Bin Zhu 是 Intel® Atom™ 处理器移动支持团队、软件和解决方案事业部(SSG)开发人员关系部门的应用工程师。他负责 Intel Atom 处理器上的 Android 应用支持,并专注于 Android x86 平台的 multimedia 技术。