Android JNI开发系列之配置

在老早之前就想要去接触了解这一块的知识了,奈何在工做中一直都没有机会去接触,就迟迟没有去学习这一块的知识。到如今终于开始去学习了,简单的搜索了一下,都没有太明确的博客去学习,都是很零碎的,并且在最新的版本中也有问题,到最后只能去看官方的文档,固然这才正确的选择,其实一开始就该去看的。废话很少说,这一个系列由于我才开始学习,不知道会有多长,可是会将经常使用的东西所有总结学习完。java

首先来学习一下官方的配置。android

1、必要的下载

这一条没啥说的,就是下载一些工具方便开发,固然是在Android Studio中。c++

对于ndk的开发,须要下载:bash

  • NDK(Native Development Kit):用来让你调用c或者c++代码的工具
  • cmake:方便在gradle中构建的,再也不使用之前的ndk-build(比较麻烦)
  • LLDB:能够调试c或者c++代码的

这三个均可以直接在SDK Manager中去下载(固然也能够手动下载配置好)。目前我使用的版本对应分别是:ide

NDK : 17.1.4828580
cmake : 3.6.4111459
LLDB : 3.1.4508709
复制代码

2、在项目中配置NDK

这一点分为两种状况:函数

  • 新建项目时配置
  • 在已有项目中配置

第一种状况没啥说的,就是在新建项目时,选中第一个界面的include C++ support这个选择框,以后一直默认next(最后finish)便可。工具

重点是第二种状况,由于大多数在在项目一开始时可能没有想着要使用ndk开发功能,后来须要了,那么就去配置便可。学习

一、建立cpp文件夹

在已有项目的main目录下建立cpp文件夹gradle

二、建立一个c文件

在cpp文件夹下建立一个c文件,右键->new->c/c++ Source File,例如取名叫作Hello,后缀名为.c,不建立.h文件,点击ok。ui

注:内部暂时能够不用写代码。

三、建立CMakeLists.txt

在当前module中建立一个CMakeLists.txt文件,右键->new->File,取名叫作CMakeLists.txt,点击ok。加上如下代码:

cmake_minimum_required(VERSION 3.4.1)

add_library( # Specifies the name of the library.
             Hello

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/Hello.c )
复制代码

add_library方法:

  • 第一个参数:Hello,就是lib的名称,以后在gradle中的ndk ModuleName一致
  • 第二个参数暂时无论
  • 第三个参数要与上文中建立的c文件路径和名字彻底相同,后缀相同

四、使用cmake配置gradle关联

选择Android视图,在须要构建的module下,右键->Link C++ Project with Gradle->选择CMakeLists.txt的路径,就是上文中建立的CMakeLists.txt,点击ok。

构建完成,能够看到在当前module下的build.gradle文件中多了如下这段话:

externalNativeBuild {
    cmake {
        path 'CMakeLists.txt'
    }
}
复制代码

这时候再在当前的build.gradle中,android模块,defaultConfig下,添加如下代码:

ndk{
    moduleName 'Hello'
}
复制代码

这里的moduleName就是要与CMakeLists.txt中定义的libraryName一致,这里加入叫Hello吧。

到此基本配置就算是完成了。下面就开始写代码,先从java调用c开始。

3、Java调用C代码

一、定义Java方法

到这一步,终于回到熟悉的Java代码,咱们在对应的包名中建立一个类,例如取名叫作Hello,加入一个简单的本地方法,只比普通抽象方法多了一个native关键字,以下:

public native String stringFromC();
复制代码

二、定义C方法

这时候这个方法是找不到的,还须要在以前的Hello.c文件中写上对应的方法,以下:

#include<jni.h>

jstring Java_net_arvin_androidstudy_jni_Hello_stringFromC(JNIEnv *env, jobject instance) {
    return (*env)->NewStringUTF(env, "I am from c!");
}
复制代码

代码不长,以此来解释,首先必需要引入的是jni.h,下边的JNIEnv和jstring,jobject等都是在这里边去定义的。

函数的申明部分,jstring表示在java中定义的String,这个位置也就是返回值,而后Java_net_arvin_androidstudy_jni_Hello_stringFromC这一部分看起来很长其实就是三个部分:Java_类的彻底限定名_方法名,只是彻底限定名中的点改成了下划线,后边的两个参数env和instance,env是一个环境,用它能够操做Java类,建立字符串之类的;instance就是当前调用这个代码的类的实例,这里就是Hello类的实例。

最后就是函数的实现内容,这里是返回一个字符串而后,看一看env这个变量的类型,JNIEnv的定义能够看到是一个typedef const struct JNINativeInterface* JNIEnv;。自己就是指针,而后在方法中的env又是指针,至关于二级指针,因此调用的时候使用的就是(*env)->函数。

三、Java代码与C代码关联

回到Hello类中,在类中加一段静态初始化的代码:

static {
    System.loadLibrary("Hello");
}
复制代码

其中Hello是上文中在build.gradle中ndk下配置的moduleName。

到这里就能够在其余地方建立Hello类的实例,而后调用stringFromC的方法了。

例如:

Hello jni = new Hello();
System.out.println(jni.stringFromC());
复制代码

就会在run tab下看到I am from c!这样一句话的输出。

至此Android JNI开发系列之配置就告一段落了。固然后边确定还有进一步的配置学习,例如须要引入多个c文件,须要引用其余c++库等,确定也是须要配置的,那些都会在以后的文章中讲到。

感谢

借鉴官方教程

相关文章
相关标签/搜索