Android NDK 使用CMake生成so

Android NDK开发目前比较流行的方式就是使用CMake,本文一个简单的hello CMake,打开NDK的门槛,我们从搭建,配置NDK环境,到输出一个aar 以及多架构的so,给任意工程调用
1. 开发环境搭建

打开Android studio 菜单键 Tools 下拉
在这里插入图片描述
进入菜单安装红色部分的插件

在这里插入图片描述
安装完毕后,重启Android studio

2. 创建主工程

注意点就是App build.gradle的配置,支持本地aar的配置,以及支持哪种so架构的目录

android {
    compileSdkVersion 29
    buildToolsVersion "30.0.0"

    defaultConfig {
        applicationId "com.immomo.ncctest"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

       
   		// 配置你的项目支持的so架构
        ndk {
            abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86'
        }

    }
    // 跟Android的代码块同级别,配置libs文件夹
	repositories {
	    flatDir {
	        dirs 'libs'
	    }
	}
3. 创建CMake NDK Module,用来编写JNI代码逻辑以及生成so和打包aar

只说重点
创建Android library项目
在这里插入图片描述
重点是library中的gradle配置

android {
    compileSdkVersion 29
    buildToolsVersion "30.0.0"

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

     
		// 这里配置cmake的信息,以及cmake编译生出的so的架构
        externalNativeBuild {
            cmake {
            	// c++ 版本信息
                cppFlags '-std=c++17'
                // 生成的so支持的架构模式
                abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86'
            }
        }

    }
}

// 跟Android代码块同级目录
    externalNativeBuild {
        cmake {
        	// cmake文件目录,
            path file('src/main/cpp/CMakeLists.txt')
            // version号
            version '3.10.2'
        }
    }


我们在Android library中建立cpp文件夹
创建名字为CMakeLists.txt的文件
在这里插入图片描述

在我们创建的CMakeLists文件中配置如下信息

// 对应build.gradle中的cmake版本
cmake_minimum_required(VERSION 3.10.2)
// 你当前创建的Android lib的名称
project("mylibrary")
// 设置library信息
add_library( 
		// 编译生成的so的名字,默认前面会自动添加lib前缀(libtest-lib)
        test-lib

        // 可以分享
        SHARED

        // ndk c++实现代码,我们需要在cmakelist同目录创建这个名字的.cpp文件
        test-lib.cpp )

find_library( 
        log-lib
        log )

target_link_libraries( 
		// 编译生成的so的名字
        test-lib
        ${log-lib} )

在这里插入图片描述

在cpp目录创建test-lib.cpp文件
紧接着我们创建我们要写在so中的代码逻辑,这里我简单的打印一个字符串展示

在这里插入图片描述
我们直接new c++file 会帮我们生成.h 和.cpp

.h文件就一个简单的声明

#ifndef NCCTEST_MYTEST_H
#define NCCTEST_MYTEST_H


extern char *libAdd(char *data);



#endif //NCCTEST_MYTEST_H

.cpp文件如下

#include "MyTest.h"
char *libAdd(char *data) {
    return data;
}

然后就是我们JNI 提供给java调用的部分

#include <jni.h>
#include <string>
#include "MyTest.h"

extern "C" {
    JNIEXPORT jstring JNICALL
    // 这里分三部分阅读
    //1.固定写法Java_ (Java层调用的)
    //2.com_test_mylibrary_MyTest_(java层调用类的包名+类名)
    //3.libAdd(java层的方法名字,需要和c++名字一致)
    Java_com_test_mylibrary_MyTest_libAdd(
            JNIEnv *env,
            jobject jobject1, jchar data) {
        std::string hello = "Hello CMake!";
        return env->NewStringUTF(hello.c_str());
    }
}

然后我们在刚才声明的目录中创建我们的JNI接口方法类,用于调用

object MyTest {
	
	// c++层的方法名
    external fun libAdd(data: Char): String?

	// 加载我们的cmake生成的so文件,记得try-catch
    init {
        try {
            System.loadLibrary("test-lib")
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}
3. 一个简单的哈喽CMkake就写完了,就差最后一哆嗦了.

我们执行build,(就是菜单栏那个绿色的小锤子按钮,如果还不知道我给你截个图哈哈哈)
在这里插入图片描述
或者你也可以在gradle菜单执行build
在这里插入图片描述
会在编译目录生成我们提供的AAR以及对应的so文件
copy出来给主工程使用吧

在这里插入图片描述
下面是我们生成的so文件,他来了

在这里插入图片描述
注意他的目录在cmake目录,
然后我们返回主工程,在lib是中把so文件copy进去
然后在build.gradle中
添加我们本地aar的依赖
在这里插入图片描述

我们在主工程中的activity中显示这个字符串,

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 这里我们在一个text上面设置so中获取的字符串
        findViewById<TextView>(R.id.sample_text).text = MyTest.libAdd('c')
    }
}

最终结果如下
在这里插入图片描述

卧槽,为啥so代码写的是hello cmake,这里显示的是什么玩意…
以为博客是后写的,编译生成的so我没有替换,只改了c.pp的字符串显示,不想替换打包了,将就着看吧.

荆轲刺秦王,随笔结束
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值