如何在Android studio中调用.so库的方法

如何在Android studio中调用.so库的方法,android,serial-port,shared-libraries,native,Android,Serial Port,Shared Libraries,Native,编辑:见我的第一个答案 我想在我的项目中使用android serialport api。这样做我有很多困难。关于如何配置较旧版本的gradle或如何使用NDK编译,存在大量相互冲突的信息,这两种信息都没有用。我完全迷路了 我发现唯一可能正确的是以下步骤: 进展#1。我将libserial\u端口.so放在src/main/jnilibs/armeabi中。当我将其作为zip文件打开时,它会显示在apk中 但是我如何告诉编译器使用这个库呢?如何告知将其包括在项目输出中?如何引用此库中的方法?(有

编辑:见我的第一个答案

我想在我的项目中使用android serialport api。这样做我有很多困难。关于如何配置较旧版本的gradle或如何使用NDK编译,存在大量相互冲突的信息,这两种信息都没有用。我完全迷路了

我发现唯一可能正确的是以下步骤:

进展#1。我将
libserial\u端口.so
放在
src/main/jnilibs/armeabi
中。当我将其作为zip文件打开时,它会显示在apk中

但是我如何告诉编译器使用这个库呢?如何告知将其包括在项目输出中?如何引用此库中的方法?(有一个
SerialPort.c
和一个
SerialPort.h
)?。把这些.mk文件放在哪里

我有种感觉,我完全错过了每个人似乎都在猜测的一条信息。在api示例中,也没有对本机库的引用

进度2:在我的代码中,我尝试使用
System.loadLibrary(“libserial_端口”)

此行抛出一个不满意的链接错误

Native code library failed to load.java.lang.UnsatisfiedLinkError: Couldn't load libserial_port from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/myapp.apk"],nativeLibraryDirectories=[/data/app-lib/myapp.apk, /vendor/lib, /system/lib]]]: findLibrary returned null
进度#3:链接器不支持带下划线的库名称

Progress#4:链接器采用lib前缀。您应该将其保留在loadlibrary命令之外

现在我调用System.loadLibrary(“serialport”);我的库名为libserialport.so。现在我再也没有不满意的链接错误了


现在开始了解如何从库中引用方法

我所有问题的答案。适用于android studio 1.5.1和gradle 2.2.1 2016年1月

  • 对于android studio,.so文件应该放在/app/src/main/jniLibs/[armeabi | armeabi-v7a | x86 |等等]中。对于eclipse,它是一个不同的目录

  • 我们不需要头文件、c文件或mk文件来工作

  • Loadlibrary在搜索库时采用“lib”前缀,因此如果要加载libdoesstuff.so,则命令应为System.Loadlibrary(“doesstuff”);我还发现一些在库名称中加下划线的语句不受支持(尽管没有测试)

  • serialport api文件应该在它自己的包中(请参阅此问题的答案:)。将SerialPort.java和SerialPortFinder.java放在/src/java/android\u SerialPort\u api中,并将它们保留在默认包中(不要将它们移动到您的项目包中,它们不会在那里工作,也不要问我如何)

  • 在要使用SerialPort类的java文件中,添加行import android\u SerialPort\u api.*

  • 如果您不想编译c代码,则无需安装NDK(许多指南都假设这一点)

  • 从当前版本的gradle(2.2.1)开始,没有必要更改任何gradle构建文件(此处的许多注释会告诉您这样做)

  • 无法在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();
        }
    }