0%

Android Studio实现JNI

JNI即Java Native Interface (Java本地接口),用来实现java代码调用C/C++代码
先前跟着吾爱一大哥的帖子做了一遍没有成功,应该是他的版本过于老旧,于是自己进行尝试。

安装LLDB和CMake

在Android Studio的File->Settings->System Settings->Android SDK->SDK Tools中选中LLDB和CMake进行安装

进行编写

  1. 创建新的Project
    在选择Template时选Native C++

  2. 看见报错提示Caused by: org.gradle.api.InvalidUserDataException: NDK not configured…
    这是因为未选定NDK路径,于是进入File->Project Structure->SDK Location中选择自己的NDK安装文件夹
    点击OK之后会发现底部框框出现CONFIGURE SUCCESSFUL字样,此时NDK配置完成

  1. 新建一个类,声明native方法。这个类是java与C/C++交互的中介,方法由java声明,由C/C++实现。

  2. 使用javac编译上述文件,生成class文件
    打开下方的Terminal即可进行编译,语句:javac E:\...\myJNI.java,之后便会多出个myJNI.class文件

  3. 进入java文件夹目录,并在里面执行javah -jni 包名.类名,然后会多出个包名_类名.h

  4. 将之前生成的.h文件移入cpp文件夹中,然后在其中创建一个新的.c或.cpp文件。将.h文件中的内容复制进入并作修改,如下:

    此时文件上方也许 会有报错提示,不用理会

  5. 配置build.gradle文件,如下图:

  1. 修改CMakeList.txt文件,如下图:

  2. 生成SO库
    点击Build->Rebuild Project即可,生成的各版本的so都在app->build->intermediates->cmake->debug->obj文件夹中

调用SO

  1. 新建jniLibs文件夹,将生成的so拷入

  2. 打开MainActivity.java插入一条log来调用so中的sayHello方法(如下图),并连接手机调试

    运行出现More than one file was found with OS independent path 'lib/x86/libJniTest.so'报错,原来是因为把各版本的so都拷入的原因,删掉其他三个,运行成功

    若出现More than one file was found with OS independent path 'lib/armeabi-v7a/libnms.so'报错,可在app->build.gradle中添加

    1
    2
    3
    4
    5
    6
    7
    8
    9
    android {

    ...

    // Fix: More than one file was found
    packagingOptions {
    pickFirst 'lib/armeabi-v7a/libnms.so'
    }
    }

关于so版本选择

armeabiv-v7a: 第7代及以上的 ARM 处理器。2011年15月以后的生产的大部分Android设备都使用它
arm64-v8a: 第8代、64位ARM处理器,很少设备,三星 Galaxy S6是其中之一
armeabi: 第5代、第6代的ARM处理器,早期的手机用的比较多
x86: 平板、模拟器用得比较多
x86_64: 64位的平板