jni 用来连接 java 和 c。

1. c文件打印 log

参考:https://blog.csdn.net/cloverjf/article/details/78683874

#define LOG_TAG    "native-dev"
#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

2. 多个 native 库,只需要修改 cmake 的文件,把 add_library() 和 target_link_libraries() 再多写一份就可以了。每个 native 库里面,有一个 JNI_OnLoad() 来注册这个库里面的函数。

参考: https://www.jianshu.com/p/106264fc07e7

#添加库
add_library( # Sets the name of the library.
             native-lib
             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp
             )
#添加库
add_library(jnilib SHARED src/main/cpp/jnilib.cpp)

#导入系统库
find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

#链接目标库
target_link_libraries( # Specifies the target library.
                       native-lib
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )
#链接目标库
target_link_libraries(jnilib ${log-lib})

3. native 库里面也可以分为多个 c 文件,来进一步模块化,解耦。但是注意一个库只有一个 JNI_OnLoad,但是可以有多个 registerNativeMethods() 注册函数。可以考虑,一个库里面专门用一个 c 文件来放 JNI_OnLoad,其他底层实现放到其他 c 文件里面,这样后期组合,只需要修改 JNI_OnLoad 的文件即可。

参考:https://blog.csdn.net/cloverjf/article/details/78878814

4. 查看本地方法的数字签名,可以到相应类的 class 生成目录下,执行 javap -s -p xxx.class,里面就有相应的输出。

参考:https://www.jianshu.com/p/b71aeb4ed13d

5. c++ 与 java 之间关于数组作为参数的使用情况,需要用:

// 复制数组
(*env)->GetIntArrayRegion(env, javaArray, 0, 10, array);

// do it

// 提交修改
(*env)->SetIntArrayRegion(env, javaArray, 0, 10, array);

上面这种需要复制数组,数组大的时候,效率低。下面这种是直接给地址的方式,不用复制,效率高。

jint *array;
jboolean isCopy;
jintArray javaArray;

// ...

array = (*env)->GetIntArrayElements(env, javaArray, &isCopy);
(*env)->ReleaseIntArrayElements(env, javaArray, array, 0);

第三个参数isCopy的作用同Java字符串转C字符串,是否为Java数组的副本。使用完之后,就要马上释放,否则会造成内存泄漏,释放函数是ReleaseArrayElements 第三个参数0代表将内容复制回来并释放原生数组。如果是JNI_COMMIT,则复制回来,但不释放。JNI_ABORT,释放但不复制回来。

参考:https://blog.csdn.net/pocoyoshamoo/article/details/24299095 https://segmentfault.com/a/1190000005658738 https://www.linuxidc.com/Linux/2014-03/97561.htm https://bbs.csdn.net/topics/390767609 https://www.cnblogs.com/lsnproj/archive/2012/01/09/2317519.html https://blog.csdn.net/csdn_of_coder/article/details/52199155 https://www.cnblogs.com/saintaxl/archive/2012/01/08/2316591.html https://www.cnblogs.com/CNty/p/10913844.html https://blog.51cto.com/4895268/1371620 https://blog.csdn.net/chaoqiangscu/article/details/83023762 https://www.cnblogs.com/xsl-thumb-rfcs/p/9955459.html https://blog.csdn.net/gao1440156051/article/details/52026718 https://www.cnblogs.com/Free-Thinker/p/6829210.html

6. android studio 需要安装 cmake, lldb, ndk,才能编译 c++ 代码。

参考:https://www.cnblogs.com/lsdb/p/9337285.html

标签: Java

添加新评论