用AS编写第一个so

用AS编写第一个so

我的gradle是 3.5.1 , Android Studio的版本是 3.5.1

找了两个小时的博客, 硬是没找到能用的... 算了, 自力更生, 丰衣足食

0x00 环境配置

  1. 确定安装了ndk, cmake, LLDB

  2. 新建项目的时候, 记得选择 Native C++

    之前版本的 include c++ support 选项在这个版本中已经独立出去了...

  3. 先配置好sdk的路径: File -> Project Structure... -> SDK Location -> Android SDK Location

    在Android视图下, 打开 local.properties , 看到ndk的路径已经配置完成

0x02 声明native方法

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

这里为了方便接下来的操作, 切换成 Project 视图

public class myJNI {
    static {
        System.loadLibrary("JniTest"); // 要加载的so的名字
    }
    public static native String sayHello();
}

虽然这里的 sayHello() 方法报错了, 但是不用管

0x03 编译与头文件的生成

  1. 使用 javac 编译上述文件, 生成class文件

  2. 确认自己的包名和类名, 然后在 java目录 使用 javah 包名.类名 命令生成 .h 头文件, 然后就能看到生成了一个 .h文件

    注意一定要在 java层目录 下输入命令, 不然不会报错: 找不到xxx类

  3. 将生成的 com_example_test_myJNI.h 拖到 cpp 目录下

  4. 然后删掉原来 cpp 目录下的 native-lib.cpp

0x04 实现头文件的函数

  1. cpp 目录下新建 main.c

  2. main.c 中的内容, 首先是将头文件包括进来, 然后实现头文件中的 sayHello 方法

    #include "com_example_test_myJNI.h"
    JNIEXPORT jstring JNICALL Java_com_example_test_myJNI_sayHello(JNIEnv *env, jclass jobj)
    {
        return (*env)->NewStringUTF(env,"hello 52pojie!");
    }

    注意: 这时候可以看到上面报错了, 先别管, 下面我们就来解决它

  3. 由于我们使用CMake来生成so的, 所以要修改 CMakeLists.txt 来指定 so名称so的源文件的相对路径

    然后 sync 一下

    发现 main.c 已经不报错了

0x05 生成so库

Build -> Rebuild Project 来生成so库

生成的so在 app\build\intermediates\cmake\debug\obj\ 或者 app\build\intermediates\merged_native_libs\debug\out\lib 或者 app\build\intermediates\stripped_native_libs\debug\out\lib\

ps: 这几个路径中的so库, 我暂时不知道区别在哪...哪位大佬知道的话, 麻烦留言说一声.

注意: 这里的so名字 = lib + 我们在CmakeLists.txt中起的名字 + .so

0x06 配置so库

app/src/main 下新建 jniLIB 目录, 并将生成的SO文件拷贝到该文件夹下

这里的so库, 我测试的时候选择的是 app\build\intermediates\merged_native_libs\debug\out\lib 路径下的, 其他的请自测

0x07 调用

打开MainActivity插入一条log来调用so中的 sayHello 方法,并连接手机调试

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章