在Android Studio 2.2及以上,构建原生库的默认工具是CMake。CMake是跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。能够输出各种各样的makefile或者project文件。CMake不直接构建出最终的软件,而是产生其他工具的脚本(如makefile),然后再依据这个工具的构建方式使用。CMake是一个比make更高级的编译配置工具,它可以根据不同的平台、不同的编译器,生成相应的makefile或vcproj项目,从而达到跨平台的目的。Android Studio利用CMake生成的是ninja。ninja是一个小型的关注速度的构建系统。我们不需要关心ninja的脚本,知道怎么配置CMake就可以了。CMake其实是一个跨平台的支持产出各种不同的构建脚本的一个工具。 2、如何配置:
- 新建一个工程,命名为TestJNI,包名为com.test.testjni点击AndroidStudio的File>Settings>Android SDK,确认SDK Tools中是否下载了NDK和CMake,如有没有就下载一份~
- 点击AndroidStudio的File>Project Structure>SDK Location, 配置 NDK路径、SDK路径 根项目的gradle.properties 中配置 android.useDeprecatedNdk=true在main文件夹下右键>New>Folder>JNI Folder项目中新建java文件TestJNI.java,写好代码 ,编译项目,编译后会在build/intermediates/javac下生成相应的.class文件,使用javah生成.h头文件,javah具体使用方式请自行百度。
package com.test.testjni; public class TestJni { static { System.loadLibrary("test_jni"); } private native int sayHello(String text); }
将.h文件放入jni文件夹下#include
在jni文件夹下,新建一个 .cpp 文件,实现 .h 内的方法即可#ifndef _Included_com_test_testjni_TestJNI #define _Included_com_test_testjni_TestJNI #ifdef __cplusplus extern "C" { #endif JNIEXPORT jint JNICALL Java_com_test_testjni_TestJni_sayHello(JNIEnv *, jobject thiz, jstring); #ifdef __cplusplus } #endif #endif #include "com_test_testjni_TestJni.h" #include
testjni的build.gradle中配置ndk和CMake相关信息#include #include #include #include #include using namespace std; #define LOG_TAG "TestJNI" #define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) extern "C" { JNIEXPORT jint JNICALL Java_com_test_testjni_TestJni_sayHello(JNIEnv *env, jobject object, jstring text) { // TODO: implement getStrFromJNI() ALOGD("usayHello start!!!!"); const char *say = env->GetStringUTFChars(text, NULL); ALOGD("usayHello start!!!! %s", say); return 100; } } plugins { id 'com.android.application' } android { compileSdkVersion 28 defaultConfig { applicationId "com.test.testjni" minSdkVersion 28 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild{ cmake{ cppFlags ""// 设置c++标准为默认 } } ndk {// 可以不配置 moduleName "test_jni" // ndk模块名字 // abiFilters "x86"// 不配置的话,默认生成所有平台的so } } // sourceSets { // main { // jniLibs.srcDirs = ['src/main/libs'] //第三方库的存放路径在此指定,不指定的话默认src/main/jniLibs // } // } externalNativeBuild{ cmake{ // version '3.10.2' path "CMakeLists.txt"// 指定CMake文件的位置 } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' }
新建CMakeLists.txt,具体描述请看本demo的CMakeLists.txt
#指定CMake构建本地库时所需的最小版本 cmake_minimum_required(VERSION 3.4.1) # 指定编译出来的so库的存放位置,方便取用给其他开发者,如果指定到jniLibs下需要在build.gradle中配置编译优先解决冲突问题。 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}) #set(LIB_DIR "${CMAKE_SOURCE_DIR}/src/main/libs") # 第三方库的存放路径,命名为LIB_DIR,下面会用到 file(GLOB source src/main/jni/testjni.cpp) add_library( # Sets the name of the library. 将资源文件生成动态链接库(so文件)的库名称(文件名称:“lib" +设置的名称) test_jni # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s).资源文件(C或C++)的相对位置 ${source} ) 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 ) #add_library(lib-add # SHARED # importED) # 引入第三方库,命名为 lib-add #set_target_properties(lib-add # PROPERTIES importED_LOCATION # ${LIB_DIR}/${ANDROID_ABI}/ddd.so) # 指定第三方库的位置、链接 target_link_libraries( # Specifies the target library.将所有的add_library中的库链接起来,有多少个add_library成的库就将其添加到这里 test_jni #这个和add_library中的指定的so库名称一致 # lib-add # links the target library to the log library # included in the NDK. ${log-lib} )
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)