环境需求
要进行jni开发,AS需要以下环境:

方式一、在工程创建的时候添加
首先使用AS(3.0)新建一个JniTest工程 
在创建工程的过程中就有是否支持jni调用的选项 
 
当你把这个选项勾选上后,你会发现项目的App模块下自动就把cmake相关的内容配置好了,我们来看看与无jni调用的工程有什么不同。 
首先,app目录下多了CMakeLists.txt文件,内容如下:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

# 配置so库信息
add_library( # Sets the name of the library.
            # 生成的so库名称,此处生成的so文件名称是libnative-lib.so
             native-lib

# Sets the library as a shared library.
             # STATIC:静态库,是目标文件的归档文件,在链接其它目标的时候使用
             # SHARED:动态库,会被动态链接,在运行时被加载
             # MODULE:模块库,是不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数动态链接
             SHARED

# Provides a relative path to your source file(s).
             # 资源文件,可以多个,
             # 资源路径是相对路径,相对于本CMakeLists.txt所在目录
             src/main/cpp/native-lib.cpp )

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

# 从系统查找依赖库
find_library( # Sets the name of the path variable.
              # android系统每个类型的库会存放一个特定的位置,而log库存放在log-lib中
              log-lib

# Specifies the name of the NDK library that
              # you want CMake to locate.
              # android系统在c环境下打log到logcat的库
              log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

# 配置库的链接(依赖关系)
target_link_libraries( # Specifies the target library.

# 目标库
                       native-lib

# Links the target library to the log library
                       # included in the NDK.
                       # 依赖于
                       ${log-lib} )

代码已经添加比较清晰的注释,使用的时候只需要拷贝到模块目录下,上方代码删除注释后一目了然,无需发愁!再看看app/build.gradle下又有什么变化:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.test.jnitest2"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}

主要的多了关于CMake的两项配置:

// android下
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt" // cmake配置文件路径
        }
    }

// defaultConfig下
            cmake {
                cppFlags ""
                // 生成多个版本的so文件
                abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
            }

具体的更多配置,请详查官方文档,根据需要修改。ok,配置就这么多,是不是很简单。接着我们看看资源目录:

我们发现系统已经帮我们把native-lib.cpp源文件写好了,根据函数名可以知道,函数的native申明是在MainActivity中。我们再看看MainActivity文件,与以前的jni调用方式完成一样:

// Used to load the 'native-lib' library on application startup.
    static {
    // 加载库
        System.loadLibrary("native-lib");
    }

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

// Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI()); // 发生jni调用
    }

/**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI(); // native申明

上面的过程包括了库的加载、native方法申明、jni方法调用三个过程。跟以往不同的是,你可以按住ctrl键鼠标左键点击native方法,也能像java一样跳转到方法的定义了,即native-lib.cpp文件中的Java_com_test_jnitest2_MainActivity_stringFromJNI方法。 
现在我们在MainActivity中再声明一个方法:

public native String getStr(String s);
1
我们选中函数名,然后alt+enter:

自动就出现了创建jni方法的选项,确定后你会在native-lib.cpp中发现函数定义框架已经写好:

so easy!你在函数中输入env->居然提示:

方式二、在项目开发过程中添加
有时候,我们的项目已经在进行中或者维护中了,突然需要使用jni调用怎么办呢?AS已经提供了相对便捷的方法。首先在要使用jni调用的工程模块下新建一个CMakeLists.txt: 
 
代码:

cmake_minimum_required(VERSION 3.6)

add_library( # Sets the name of the library.
             xjni

# Sets the library as a shared library.
             SHARED

# Provides a relative path to your source file(s).
             src/main/jni/XJni.c )

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 )

target_link_libraries( # Specifies the target library.
              xjni

# Links the target library to the log library
              # included in the NDK.
              ${log-lib} )

CMakeLists.txt具体配置上面已经说过了,这个地方是去掉了注释了的。需要注意的是,如果我们不在c源代码文件中输出日志到logcat,那么我们是不需要依赖log库的,也就是说find_library、target_link_libraries不是必须的。 
接着配置模块支持jni调用,对项目模块右键: 
 
在弹出的提示框中选择刚新建配置的CMakeLists.txt文件: 
 
我们看看app/build.gradle有什么变化:

编译完成,编译器会报找不到XJni.c文件错误。ok,那我们新建一个/app/src/main/jni/XJni.c:

#include <jni.h>
1
只有一行代码,ok,再编译,没问题!接下来新建jni调用java文件XJni.java:

package com.test.jnitest4;

public class XJni {

static {
        System.loadLibrary("xjni");
    }

public native String getStr(String s);
}

getStr方法显示错误红色,不用着急,我们选中函数名,按快捷键alt+enter:

选择create function后,函数就自动在XJni.c文件中生成了

#include <jni.h>

JNIEXPORT jstring JNICALL
Java_com_test_jnitest4_XJni_getStr(JNIEnv *env, jobject instance, jstring s_) {
    const char *s = (*env)->GetStringUTFChars(env, s_, 0);

// TODO

(*env)->ReleaseStringUTFChars(env, s_, s);

return (*env)->NewStringUTF(env, returnValue);
}

android CMake开发相关推荐

  1. Android NDK开发之旅(2):一篇文章搞定Android Studio中使用CMake进行NDK/JNI开发

    Android NDK开发之旅(2):一篇文章搞定android Studio中使用CMake进行NDK/JNI开发 (码字不易,转载请声明出处:http://blog.csdn.NET/andrex ...

  2. 【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )

    文章目录 I . FFMPEG 交叉编译后的函数库及头文件 II . FFMPEG 静态库打包动态库 ( 仅做参考 ) III . 创建 Android Studio 工程 IV . FFMPEG 头 ...

  3. 【Android NDK 开发】Android Studio 使用 CMake 导入动态库 ( 构建脚本路径配置 | 指定动态库查找路径 | 链接动态库 )

    文章目录 I . CMake 引入动态库与静态库区别 II . Android Studio 中 CMake 引入动态库流程 III . 指定动态库查找路径 IV . 链接函数库 V . 完整代码示例 ...

  4. 【Android NDK 开发】Android Studio 使用 CMake 导入静态库 ( CMake 简介 | 构建脚本路径配置 | 引入静态库 | 指定静态库路径 | 链接动态库 )

    文章目录 I . CMake 简介 II . Android Studio 中 CMake 引入静态库流程 III . 指定 CMake 最小版本号 IV . 导入函数库 ( 静态库 / 动态库 ) ...

  5. 【Android NDK 开发】Android.mk 配置动态库 ( Android Studio 配置动态库 | 动态库加载版本限制 | 本章仅做参考推荐使用 CMake 配置动态库 )

    文章目录 I . Android Studio 中使用 Android.mk 配置动态库 总结 II . 第三方动态库来源 III . 配置 Android.mk 构建脚本路径 IV . 预编译 第三 ...

  6. 【Android NDK 开发】Android Studio 的 NDK 配置 ( 源码编译配置 | 构建脚本配置 | 打包配置 | CMake 配置 | ndkBuild 配置 )

    文章目录 I . 源码编译配置 II . 构建脚本配置 III . NDK 函数库打包配置 IV . Java 与 C 代码示例 V . CMake 配置 ( CMakeLists.txt ) VI ...

  7. 【Android NDK 开发】Visual Studio 2019 使用 CMake 开发 JNI 动态库 ( 动态库编译配置 | JNI 头文件导入 | JNI 方法命名规范 )

    文章目录 I . JNI 与 NDK 区别 II . Visual Studio 编译动态库 III. 配置 导入 jni.h 头文件 IV . IntelliJ IDEA Community Edi ...

  8. 哪位大兄弟有用 cMake 开发Android ndk的

    一直用 Android studio 开发ndk,但是gradle支持的不是很好,只有experimental 版本支持 配置各种蛋疼.主要每次新建一个module都要修改配置半天. 之前也看到过go ...

  9. android cmake 打印_Android NDK 开发:CMake 使用

    1. 前言 当在做 Android NDK 开发时,如果不熟悉用 CMake 来构建,读不懂 CMakeLists.txt 的配置脚本,很容易就会踩坑,遇到编译失败,一个很小的配置问题都会浪费很多时间 ...

最新文章

  1. 共阳极数码管动态扫描c语言,《C语言编程实训》实训指导书三
  2. Office 2007 文件扩展名类型
  3. 原生JS forEach()和map()遍历的区别以及兼容写法
  4. android list 替换元素_Python数据结构(一)List使用(大厂面试解答)
  5. 【HTML/CSS】margin塌陷和合并问题
  6. python 计量经济 35岁 工作_Python在计量经济与统计学中的应用
  7. 自动为人脸上色,Adobe的涂鸦AI想让世界更多彩
  8. XenApp 6安装过程中的两个常见错误
  9. mysql 5.6.15 winx64_mysql-5.6.15-winx64免安装 配置步骤
  10. linux下安装weblogic出现的两个错误解决办法
  11. kali 更新后出现乱码的解决方案
  12. oracle gho系统吗,系统镜像GHO、WIM、ESD几种格式的区别
  13. ubuntu22.04安装dde桌面
  14. layui table 获取单元格总是多一个
  15. web程序发布后发送传真失败记要
  16. 英语作文模板句型,考试必背!
  17. IBM董事长亲自站台,开源为什么对IBM这么重要?
  18. openfire--好友管理各种状态纠结
  19. 狼人杀校园升级版:学霸大战学渣 Who is the king of examination!
  20. GIS-空间分析(1)

热门文章

  1. 4g模块注册上网 移远_Openwrt实现4G模块上网功能
  2. 撒列实现关键字过虑二(附源码)
  3. vs2017通过snippet代码片断进行标准化注释
  4. 准备mysql函数库和PHP文件
  5. 使用navicat工具创建MySQL存储过程
  6. Jquery Ajax时 error处理 之 parsererror
  7. 完美世界推穿戴式设备:能消灭“宅玩家”吗?
  8. koa+mysql+vue+socket.io全栈开发之web api篇
  9. 大名鼎鼎的Requests库用了什么编码风格?
  10. java -IO流_字符流