根据前面学习的c学习的基础知识,在as下,进行手动的ndk开发
1.在java类中先写native方法,并且加载将将要生成的c或c++的文件的名称。这里的JNIHello就是我们要创建的c或c++的文件。
2.在terminal的命令行中输入命令生成头文件
javah -d …/jni com.xxx.xxx 。其中-d是生成文件夹的意思
3.在生成的jni文件夹中,右键创建c或c++代码。创建JNIHello.c文件。在文件中要进行导入生成的头文件。
4.由于as现在支持cmake的构建ndk的方法,原有的方法比如在工程目录下的gradle.properties中添加
都是无效的。
因此应该app的gradle下面做相应的cmake的配置
在android–> defaultConfig下面添加
5.在android下面添加,否则会默认只生成一个平台的so文件
6.指定cmake文件的路径
7.创建CMakeLists.txt文件
8.CMakeLists.txt的内容,并根据提示进行相应的修改
cmake_minimum_required(VERSION 3.4.1)
add_library( # Sets the name of the library.
JNIHello
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/jni/JNIHello.c )
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.
JNIHello
# Links the target library to the log library
# included in the NDK.
${log-lib} )
9.最后在下面目录中找到so文件
其相应的配置都可以参考as默认创建的jni。在创建工程时,选择c++支持。就可以创建默认应用。
具体项目:https://github.com/yunzheyue/JniTest
扩展:
https://blog.youkuaiyun.com/yuezheyue123/article/details/81028233
动态库和静态库的区别
Android中只支持调用so动态库,不支持a静态库的,那么这…集成a静态库这不是扯淡么?
OK,接下来就来解释这一系列的问题,首先我们要知道什么是静态库什么又是动态库。
静态库
链接时间: 静态库的代码是在编译过程中被载入程序中;
链接方式: 目标代码用到库内什么函数,就去将该函数相关的数据整合进目标代码;
优点: 是在编译后的执行程序不在需要外部的函数库支持;
缺点: 如果所使用的静态库发生更新改变,程序必须重新编译。
动态库
链接时间: 动态库在编译的时候并没有被编译进目标代码,而是在运行时用到该库中函数时才去调用;
链接方式: 动态链接,用到该库内函数时就去加载该库;
优点: 动态库的改变并不影响程序,即不需要重新编译;
缺点: 因为函数库并没有整合进程序,所以程序的运行环境必须依赖该库文件。
再精简一点:
静态库是一堆cpp文件,每次都需要编译才能运行,在自己的代码中用到哪个,就从这一堆cpp中取出自己需要的进行编译;
动态库是将一堆cpp文件都编译好了,运行的时候不会对cpp进行重新编译,当需要到库中的某个函数时,就会将库加载进来,不需要时就不用加载,前提,这个库必须存在。
所以,就可以回答上述的疑问了,对,没错Android的确是只能调用so动态库,我们的集成的a静态库,用到静态库中的函数时,就会去静态库中拿对应的元数据,然后将这些数据再打入到打入到我们的最终要调用的so动态库中,在上述中就是native_hello.so了。