Android开发之基于CMake的JNI开发详细介绍

Android开发之基于CMake的JNI开发详细介绍,第1张

Android开发之基于CMake的JNI开发详细介绍 1、什么是CMake:

在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,如有没有就下载一份~

  1. 点击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 
    
    
    #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
    
    在jni文件夹下,新建一个 .cpp 文件,实现 .h 内的方法即可
    #include "com_test_testjni_TestJni.h"
    #include 
    #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;
    }
    
    }
    testjni的build.gradle中配置ndk和CMake相关信息
    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} )

 

 

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5710300.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存