我想在我的项目中使用android serialport api.这样做我有很多麻烦.关于如何配置旧版本的gradle或如何使用NDK编译这些都没有用,存在大量相互矛盾的信息.我完全迷失了.
我发现的唯一可能是正确的是以下步骤:
进步#1.我将libserial_port.so放在src/main/jnilibs/armeabi中.当我将其作为zip文件打开时,它出现在apk中.
但是,如何告诉编译器使用此库?如何判断将其包含在项目输出中?如何引用此库中的方法?(有一个SerialPort.c和一个SerialPort.h)?在哪里放这些.mk文件?
我感觉我完全错过了每个人似乎都认为的信息.在api示例中,也没有引用本机库.
进度#2:在我的代码中,我尝试使用
System.loadLibrary("libserial_port")加载库;
该行抛出UnsatisfiedLinkError.本机代码库无法加载.java.lang.UnsatisfiedLinkError:无法从加载器dalvik.system.PathClassLoader加载libserial_port [DexPathList [[zip文件"/data/app/myapp.apk"],nativeLibraryDirectories=[/data/app -lib/myapp.apk,/ vendor/lib,/ system/lib]]]:findLibrary返回null
进度#3:链接器不支持带下划线的库名.
进度#4:链接器采用lib前缀.你应该将它从loadlibrary命令中删除.
现在我调用System.loadLibrary("serialport"); 我的图书馆名为libserialport.so.现在我不再得到UnsatisfiedLinkError了!
现在关闭以了解如何从lib引用方法.
回答我的所有问题.适用于Android studio 1.5.1 with gradle 2.2.1 2016年1月.
使用android studio,.so文件应该放在/ app/src/main/jniLibs/[armeabi | armeabi-v7a | x86 | etcetera].对于eclipse,它是一个不同的目录.
我们不需要header,c文件或mk文件来实现这一点.
Loadlibrary在搜索库时假定为"lib"前缀,因此如果要加载libdoesstuff.so,则命令应为System.loadLibrary("doesstuff"); 我还发现了一些不支持lib名称中的下划线的语句(虽然没有测试).
serialport api文件应该在它自己的包中(参见这个问题的答案:如何在Android上用Java单元测试串口).放置SerialPort.java和SerialPortFinder.java在/ src目录/ JAVA/android_serialport_api并让他们在默认包(不要将它们移动到你的项目包,他们将在那里工作,不要问我怎么样).
在要使用SerialPort类的java文件中,添加行import android_serialport_api.*;
如果您不想编译c代码,则无需安装NDK(很多指南都假设这样).
从当前版本的gradle(2.2.1)开始,无需更改任何gradle构建文件(SO上的很多注释都会告诉您这样做).
您无法在Android Studio的项目设置中添加.so文件.将lib放在jniLibs中会将.so添加到APK.
完整示例(线程读取串行输入).
package com.yourpackage; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter;import java.util.Set; import android_serialport_api.SerialPort; public class SerialPortReader { private Thread readSerialDataThread; private SerialPort serialPort; private InputStream inStream; private OutputStream outStream; private boolean shouldRun = true; public SerialPortReader() { } protected void start() { try { File portLocation = new File("/dev/ttyS1"); serialPort = new SerialPort(portLocation, 9600, 0); inStream = serialPort.getInputStream(); outStream = serialPort.getOutputStream(); sendBytes(); } catch (IOException e) { Log.e("SerialPort", "IOException while opening serial port: " + e.getMessage()); e.printStackTrace(); } startThread(); } protected void stop() { // break thread this.shouldRun = false; try { readSerialDataThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } serialPort.close(); } private void sendBytes() { // example how to send data to the opened serial port byte[] data = new byte[]{(byte) 0xFF, (byte) 0xAA, (byte) 0x64}; try { outStream.write(data); } catch (IOException e) { e.printStackTrace(); } } private void startThread() { readSerialDataThread = new Thread(new Runnable() { public void run() { while (shouldRun) { int dataSize = 0; try { dataSize = inStream.available(); byte[] data = new byte[dataSize]; inStream.read(data); processData(data); Thread.sleep(50); // my serial sensor gives 20 Hz updates } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } }); readSerialDataThread.start(); } }