1.官网
https://developer.android.com/studio/projects/add-native-code.html
2.android studio 安装相关工具
- 在打开的项目中,从菜单栏选择 Tools > Android > SDK Manager。
- 点击 SDK Tools 标签。
- 选中 LLDB、CMake 和 NDK 旁的复选框,如图所示.
3.新建支持c/c++的项目
- 在android studio 3.4.1 新建向导里选 Native C++ 模板.
2.选择想要使用的c++标准,如C++14.
3.最后 生成的项目如下:
其中:
-
- CMakeLists.txt 是cmake构建工程要用的项目配置文件.
- native-lib.cpp是源文件
4.编辑代码,使用本地程序....
4.在现有项目中添加 c/c++库
4.1 创建 jni目录
项目名(或者File) ---> 右键 ---> New ---> Folder ---> JNI Folder
4.2 创建 CMakeLists.txt文件
在上一步上创建的jni目录(当前版本目录名是cpp) 右键 ---> New ---> File 输入CMakeLists.txt
4.3 配置CMakeLists.txt 文件
1 # Sets the minimum version of CMake required to build your native library. 2 # This ensures that a certain set of CMake features is available to 3 # your build. 4 5 cmake_minimum_required(VERSION 3.4.1) 6 7 # Specifies a library name, specifies whether the library is STATIC or 8 # SHARED, and provides relative paths to the source code. You can 9 # define multiple libraries by adding multiple add.library() commands, 10 # and CMake builds them for you. When you build your app, Gradle 11 # automatically packages shared libraries with your APK. 12 13 add_library( # Specifies the name of the library. 14 # 本地库名 15 student-lib 16 17 # Sets the library as a shared library. 18 # 本地库的类型 19 SHARED 20 21 # Provides a relative path to your source file(s). 22 # 要编译的源文件 ,多个之间用空格. 23 student.cpp school.cpp) 24 25 # Specifies a path to native header files. 26 include_directories(inc) 27 28 29 #添加本地代码依赖的其它系统库. 30 find_library( # Defines the name of the path variable that stores the 31 # location of the NDK library. 32 log-lib 33 34 # Specifies the name of the NDK library that 35 # CMake needs to locate. 36 log ) 37 38 # Links your native library against one or more other native libraries. 39 target_link_libraries( # Specifies the target library. 40 student-lib 41 42 # Links the log library to the target library. 43 ${log-lib} )
- 注意CMakeLists.txt中源文件和include的路径引用问题,这里是和源文件同级.
- CMakeLists.txt 常用函数含义
- 下面是常用的cmake命令.
cmake命令官网 : https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html
add_library() |
向您的 CMake 构建脚本添加源文件或库 1 add_library( # Specifies the name of the library. 2 native-lib 3 4 # Sets the library as a shared library. 5 SHARED 6 7 # Provides a relative path to your source file(s). 8 src/main/cpp/native-lib.cpp ) |
include_directories |
指定头文件的路径 1 add_library(...) 2 3 # Specifies a path to native header files. 4 include_directories(src/main/cpp/include/) |
find_library() |
添加引用的NDK 库 1 find_library( # Defines the name of the path variable that stores the 2 # location of the NDK library. 3 log-lib 4 5 # Specifies the name of the NDK library that 6 # CMake needs to locate. 7 log ) |
target_link_libraries() |
链接多个库 1 target_link_libraries( native-lib imported-lib app-glue ${log-lib} ) |
add_library() |
将其它源代码编译到本地库中. 1 add_library( app-glue 2 STATIC 3 ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c ) 4 5 # You need to link static libraries against your shared native library. 6 target_link_libraries( native-lib app-glue ${log-lib} ) |
set_target_properties 和 IMPORTED |
IMPORTED不是个函数,只是add_library的参数,添加其他预构建的本地库 然后,您需要使用 set_target_properties() 命令指定库的路径. |
4.4 关联Gradle与 CMakeLists.txt
右键点击您想要关联的模块(例如 app 模块),并从菜单中选择 Link C++ Project with Gradle。关联到之前创建的CMakeLists.txt,点OK.
4.5 完成本地的c/c++代码工作
MainActivity.java
1 public class MainActivity extends AppCompatActivity { 2 3 // Used to load the 'native-lib' library on application startup. 4 static { 5 System.loadLibrary("native-lib"); 6 } 7 8 @Override 9 protected void onCreate(Bundle savedInstanceState) { 10 super.onCreate(savedInstanceState); 11 setContentView(R.layout.activity_main); 12 13 // Example of a call to a native method 14 TextView tv = findViewById(R.id.sample_text); 15 tv.setText(stringFromJNI()); 16 } 17 18 /** 19 * A native method that is implemented by the 'native-lib' native library, 20 * which is packaged with this application. 21 */ 22 public native String stringFromJNI(); 23 }
native-lib.cpp
1 #include <jni.h> 2 #include <string> 3 4 extern "C" JNIEXPORT jstring JNICALL 5 Java_com_example_cpp14_MainActivity_stringFromJNI( 6 JNIEnv* env, 7 jobject /* this */) { 8 std::string hello = "Hello from C++"; 9 return env->NewStringUTF(hello.c_str()); 10 }
5.在 Gradle 中使用 CMake 变量
https://developer.android.com/ndk/guides/cmake.html#variables
1 android { 2 ... 3 defaultConfig { 4 ... 5 // This block is different from the one you use to link Gradle 6 // to your CMake or ndk-build script. 7 externalNativeBuild { 8 9 // For ndk-build, instead use ndkBuild {} 10 cmake { 11 12 // Passes optional arguments to CMake. 13 arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang" 14 15 // Sets optional flags for the C compiler. 16 cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2" 17 18 // Sets a flag to enable format macro constants for the C++ compiler. 19 cppFlags "-D__STDC_FORMAT_MACROS" 20 } 21 } 22 } 23 24 buildTypes {...} 25 26 ... 27 }
6.指定本地库的cpu架构
默认情况下,Gradle 会针对 NDK 支持的 ABI 将您的原生库构建到单独的 .so
文件中,并将其全部打包到您的 APK 中。如果您希望 Gradle 仅构建和打包原生库的特定 ABI 配置,您可以在模块级 build.gradle
文件中使用 ndk.abiFilters
标志指定这些配置.
1 apply plugin: 'com.android.application' 2 3 android { 4 compileSdkVersion 28 5 defaultConfig { 6 applicationId "com.example.tocpp5" 7 minSdkVersion 15 8 targetSdkVersion 28 9 versionCode 1 10 versionName "1.0" 11 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 12 // This block is different from the one you use to link Gradle 13 // to your CMake or ndk-build script. 14 externalNativeBuild { 15 // For ndk-build, instead use ndkBuild {} 16 cmake { 17 // Passes optional arguments to CMake. 18 arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang" 19 20 // Sets optional flags for the C compiler. 21 cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2" 22 23 // Sets a flag to enable format macro constants for the C++ compiler. 24 cppFlags "-D__STDC_FORMAT_MACROS" 25 26 abiFilters 'armeabi-v7a','arm64-v8a' 27 28 } 29 } 30 ndk { 31 // Specifies the ABI configurations of your native 32 // libraries Gradle should build and package with your APK. 33 abiFilters 'x86', 'x86_64', 'armeabi-v7a','arm64-v8a' 34 } 35 } 36 buildTypes { 37 release { 38 minifyEnabled false 39 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 40 } 41 } 42 externalNativeBuild { 43 cmake { 44 path file('src/main/jni/CMakeLists.txt') 45 } 46 } 47 } 48 49 dependencies { 50 implementation fileTree(dir: 'libs', include: ['*.jar']) 51 implementation 'androidx.appcompat:appcompat:1.0.2' 52 implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 53 testImplementation 'junit:junit:4.12' 54 androidTestImplementation 'androidx.test:runner:1.2.0' 55 androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 56 }
在 defaultConfig.externalNativeBuild.cmake {}
块
或
defaultConfig.externalNativeBuild.ndkBuild {}
块
中配置另一个 abiFilters
标志。Gradle 会构建defaultConfig.ndk中的 ABI 配置,不过仅会打包在 defaultConfig.
块中指定的配置。cmake或者
{}ndkBuild
注: 非特殊情况下,只保留 'arm64-v8a' 就够用了。 参考微信的apk。