安卓ndk编译的两种方式(ndk-build和cmake)配置

知识点整理

  • 1.ndk-build

1.ndk-build

动态加载JNI
1.java 层代码:

    static {
        System.loadLibrary("MyLibrary"); // libxxx.so库的  libMyLibrary.so
    }

2.jni C++
(1)在main目录下新建一个jni目录,里面的.cpp最终要生成.so 库,加载进apk里面

在这里插入代码片

(2) 创建Android.mk Application.mk文件 编译脚本

Android.mk

    #每个Android.mk文件必须以LOCAL_PATH开头,在整个开发中,它通常别用做定位资源文件,例如,功能宏my-dir提供给编译系统当前的路径。
    LOCAL_PATH := $(call my-dir)
    
    #CLEAR_VARS指编译系统提供一个特殊的GUN MakeFile来为你清除所有的LOCAL_XXX变量,LOCAL_PATH不会被清除。使用这个变量是因为在编译系统时,所有的控制文件都会在一个GUN Make上下文进行执行,而在此上下文中所有的LOCAL_XXX都是全局的。
    include $(CLEAR_VARS)
    
    #LOCAL_MODULE变量是为了确定模块名,并且必须要定义。这个名字必须是唯一的同时不能含有空格。会自动的为文件添加适当的前缀或后缀,模块名为“foo”它将会生成一个名为“libfoo.so”文件。
    LOCAL_MODULE := myjni
    
    #包含一系列被编译进模块的C 或C++资源文件
    LOCAL_SRC_FILES := JNI_C++.cpp
    
    #指明一个GUN Makefile脚本,并且收集从最近“include$(CLEAR_VARS)”下的所有LOCALL_XXX变量的信息,最后告诉编译系统如何正确的进行编译。将会生成一个静态库hello-jni.a文件或者动态库libhello-jni.so。
    include $(BUILD_SHARED_LIBRARY)

总结:
LOCAL_PATH即为调用命令的所在目录,你在哪个目录下使用cmd命令,这里就会返回它的路径地址
LOCAL_MODULE你生成的文件名称是什么,输出之后会自动在名称的前后加上lib和.so
LOCAL_SRC_FILES要对哪个文件进行编译

Application.mk
可没有,主要指定so调用库名以及编译的so对应CPU平台
若没有,则可在build.gradle中设置,此时使用系统进行编译,而非使用ndk-build

    APP_MODULES := MyJni
    APP_ABI := all all代表全平台

3.编译方式选择:
在app module目录下的build.gradle中设置库文件名(生成的so文件名)。找到gradle文件的defaultConfig这项,在里面添加如下内容:

//第一种是将c++ 文件生成.so 库
defaultConfig { 
    ...... 
    ndk{ 
        moduleName "JniLibName"  //生成的so名字
        ldLibs "log", "z", "m"  //添加依赖库文件,如果有log打印等 
        abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定cpu体系结构下的so库。 
    } 
}
 
externalNativeBuild {  
          ndkBuild { path file("src/main/java/jni/Android.mk") 
    } 
}
sourceSets {
    main {
        jni.srcDirs('src/main/java/jni')
    }
}
此种生成的so文件在app/build/intermediates/ndkBuild/debug下



//第二种是 指定将已经有的.so 编译进apk里面
    sourceSets {
        main {
            jniLibs.srcDirs('.\\libs')        这种是指定.so 文件编译进apk里面,如果在main目录下已经有个JniLibs目录则不用指定,编译时自动会编译进去
        }
    }

你可能感兴趣的:(android,NDK)