IV . Java 与 C 代码示例
1 . Java 代码 :
package kim.hsl.compile; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends AppCompatActivity { static { //此处只能加载动态库 , 不能加载静态库 System.loadLibrary("native-lib"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = findViewById(R.id.sample_text); tv.setText(stringFromJNI()); } public native String stringFromJNI(); }
2 . C 代码 :
#include <jni.h> #include <android/log.h> JNIEXPORT jstring JNICALL Java_kim_hsl_compile_MainActivity_stringFromJNI( JNIEnv *env, jobject obj) { __android_log_print(ANDROID_LOG_INFO, "JNI_TAG", "Hello from C"); return (*env)->NewStringUTF(env, "Hello from C"); }
V . CMake 配置 ( CMakeLists.txt )
1 . CMakeLists.txt 配置示例 :
# 声明 CMake 版本 cmake_minimum_required(VERSION 3.4.1) # 添加库 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). native-lib.c) # 到预设的目录查找 log 库 , 将找到的路径赋值给 log-lib # 这个路径是 NDK 的 ndk-bundle\platforms\android-29\arch-arm\usr\lib\liblog.so # 不同的 Android 版本号 和 CPU 架构 需要到对应的目录中查找 , 此处是 29 版本 32 位 ARM 架构的日志库 find_library( log-lib log) # 链接库 target_link_libraries( native-lib ${log-lib})
2 . 对应的 build.gradle 中的 NDK 配置 :
apply plugin: 'com.android.application' android { ... /* 关于 CPU 指令集 NDK 17 以上只支持 armeabi-v7a, arm64-v8a, x86, x86-64 四种 CPU 指令集架构 */ // 配置 AS 工程中的 C/C++ 源文件的编译 // defaultConfig 内部的 externalNativeBuild 配置的是配置 AS 工程的 C/C++ 源文件编译参数 // defaultConfig 外部的 externalNativeBuild 配置的是 CMakeList.txt 或 Android.mk 构建脚本的路径 externalNativeBuild { cmake { cppFlags "" //配置编译 C/C++ 源文件为哪几个 CPU 指令集的函数库 (arm , x86 等) abiFilters "armeabi-v7a" , "arm64-v8a", "x86", "x86_64" } } //配置 APK 打包 哪些动态库 // 示例 : 如在工程中编译的函数库 , 其提供了 arm, x86, mips 等指令集的动态库 // 那么为了控制打包后的应用大小, 可以选择性打包一些库 , 此处就是进行该配置 ndk{ // 打包生成的 APK 文件指挥包含 ARM 指令集的动态库 abiFilters "armeabi-v7a" , "arm64-v8a", "x86", "x86_64" } } // 配置 NDK 的编译脚本路径 // 编译脚本有两种 ① CMakeList.txt ② Android.mk // defaultConfig 内部的 externalNativeBuild 配置的是配置 AS 工程的 C/C++ 源文件编译参数 // defaultConfig 外部的 externalNativeBuild 配置的是 CMakeList.txt 或 Android.mk 构建脚本的路径 externalNativeBuild { // 配置 CMake 构建脚本 CMakeLists.txt 脚本路径 // 使用该配置时 , 将 ndkBuild 配置注释掉 cmake { path "src/main/cpp/CMakeLists.txt" version "3.10.2" } // 配置 Android.mk 构建脚本路径 // 使用该配置时 , 将 cmake 配置注释掉 /*ndkBuild{ path "src/main/cpp/Android.mk" }*/ } ... } ...
VI . ndkBuild 配置 ( Android.mk )
1 . Android.mk 配置示例 :
# my-dir 是 NDK 内置的函数 , 获取当前的目录路径 # 在该案例中就是 Android.mk 文件所在的目录的绝对路径 , 工程根目录/app/src/main/cpp # 将该目录赋值给 LOCAL_PATH 变量 # 所有的 Android.mk 的第一行配置都是该语句 LOCAL_PATH := $(call my-dir) # 打印 LOCAL_PATH 值 # Build 打印内容 : LOCAL_PATH : Y:/002_WorkSpace/001_AS/005_NDK_Compile/app/src/main/cpp # 编译 APK 时会在 Build 中打印 $(info LOCAL_PATH : $(LOCAL_PATH)) # 配置新的模块之前都要先清除 LOCAL_XXX 变量 # LOCAL_PATH 变量会保留 include $(CLEAR_VARS) # 配置动态库名称 # 动态库命名规则 : 在 LOCAL_MODULE 基础上 , 添加 lib 前缀 和 .so 后缀 # 生成动态库名称 : libnative-lib.so LOCAL_MODULE := native-lib # 编译的源文件 LOCAL_SRC_FILES := native-lib.c # 配置构建的目标是动态库 include $(BUILD_SHARED_LIBRARY)
2 . 对应的 build.gradle 中的 NDK 配置 :
apply plugin: 'com.android.application' android { ... /* 关于 CPU 指令集 NDK 17 以上只支持 armeabi-v7a, arm64-v8a, x86, x86-64 四种 CPU 指令集架构 */ // 配置 AS 工程中的 C/C++ 源文件的编译 // defaultConfig 内部的 externalNativeBuild 配置的是配置 AS 工程的 C/C++ 源文件编译参数 // defaultConfig 外部的 externalNativeBuild 配置的是 CMakeList.txt 或 Android.mk 构建脚本的路径 externalNativeBuild { cmake { cppFlags "" //配置编译 C/C++ 源文件为哪几个 CPU 指令集的函数库 (arm , x86 等) abiFilters "armeabi-v7a" , "arm64-v8a", "x86", "x86_64" } } //配置 APK 打包 哪些动态库 // 示例 : 如在工程中编译的函数库 , 其提供了 arm, x86, mips 等指令集的动态库 // 那么为了控制打包后的应用大小, 可以选择性打包一些库 , 此处就是进行该配置 ndk{ // 打包生成的 APK 文件指挥包含 ARM 指令集的动态库 abiFilters "armeabi-v7a" , "arm64-v8a", "x86", "x86_64" } } // 配置 NDK 的编译脚本路径 // 编译脚本有两种 ① CMakeList.txt ② Android.mk // defaultConfig 内部的 externalNativeBuild 配置的是配置 AS 工程的 C/C++ 源文件编译参数 // defaultConfig 外部的 externalNativeBuild 配置的是 CMakeList.txt 或 Android.mk 构建脚本的路径 externalNativeBuild { // 配置 CMake 构建脚本 CMakeLists.txt 脚本路径 // 使用该配置时 , 将 ndkBuild 配置注释掉 /*cmake { path "src/main/cpp/CMakeLists.txt" version "3.10.2" }*/ // 配置 Android.mk 构建脚本路径 // 使用该配置时 , 将 cmake 配置注释掉 ndkBuild{ path "src/main/cpp/Android.mk" } } ... } ...
VII . 博客相关资源下载
CSDN 博客地址 : 【Android NDK 开发】Android Studio 的 NDK 配置 ( 源码编译配置 | 构建脚本配置 | 打包配置 | CMake 配置 | ndkBuild 配置 )
博客资源下载地址 : https://download.csdn.net/download/han1202012/12152060
示例代码 GitHub 地址 : https://github.com/han1202012/005_NDK_Compile