当前位置:网站首页 > Java基础 > 正文

java基础类编写



在进行Android开发的过程中,我们必定会遇到视频图像处理、高强度密集运算、特殊算法等场景,这时我们就不得不需要去接触一些C/C++代码,进行JNI开发。下面我将从Android.mk和CMake这两种方式教大家如何进行开发。文章结尾将给出演示的项目代码,如果你能耐心地仔细看完,相信你一定能掌握如何在Android下进行JNI开发。

使用Android.mk进行JNI开发

1.编写native接口和C/C++代码

定义native接口

代码语言:javascript
复制
 
 

编写C/C++代码

代码语言:javascript
复制
 
 

2.编写Android.mk

模版如下:

代码语言:javascript
复制
 
 

说明:

(1) :指向当前目录的地址,包含该.mk

(2):清理掉所有以LOCAL_开头的内容,这句话是必须的,因为如果所有的变量都是全局的,所有的可控的编译文件都需要在一个单独的GNU中被解析并执行。

(3):调用的库名,用来区分android.mk中的每一个模块。文件名必须是唯一的,不能有空格。注意,这里编译器会为你自动加上一些前缀lib和后缀.so,来保证文件是一致的。

(4):变量必须包含一个C、C++或者java源文件的列表,这些会被编译并聚合到一个模块中,文件之间可以用空格或Tab键进行分割,换行请用""

(5):定义需要链接的库。一般用于链接那些存在于系统目录下本模块需要链接的库(比如这里的logcat库)。

(6):来生成一个动态库libnative-lib.so

3.编写Application.mk

代码语言:javascript
复制
 
 

说明:

(1):定义编译so文件的CPU型号,all为所有类型。也可以指定特定类型的CPU型号,直接使用空格隔开。

(2):优化选项,非必填。其值可以为'release'或'debug'.此变量用来修改优先等级.默认情况下为release.在release模式下,将编译生成被优化了的二进制的机器码,而debug模块用来生成便于调试的未被优化的二进制机器码。

(3):选择支持的C++标准库。在默认情况下,NDK通过Androoid自带的最小化的C++运行库(system/lib/libstdc++.so)来提供标准C++头文件.然而,NDK提供了可供选择的C++实现,你可以通过此变量来选择使用哪个或链接到你的程序。

代码语言:javascript
复制
 
 

比如,这里我们使用到了 ,就需要设置

4.设置项目根目录的local.properties文件

因为Android Studio 2.2以后推荐使用CMake进行JNI开发,因此需要修改一下参数进行兼容。

代码语言:javascript
复制
 
 

5.编译C/C++代码生成so文件

cd 到jni(存放Android.mk的目录)下,执行 即可。

执行成功后,将会在jni的同级目录下生成 和 文件夹,存放的是编译好的so文件。

6.在模块的build.gradle中设置so文件路径

代码语言:javascript
复制
 
 

至此完成了Android.mk的设置,下面我们就可以愉快地进行jni开发了!


上面介绍的Android.mk都可以在Eclispe和Android Studio下进行编译开发,可以说是一种比较传统的做法。下面我将介绍Android Studio着重推荐的CMake方式进行JNI开发。

使用CMake进行JNI开发

开发环境

JNI:Java Native Interface(Java 本地编程接口),一套编程规范,它提供了若干的 API 实现了 Java 和其他语言的通信(主要是 C/C++)。Java 可以通过 JNI 调用本地的 C/C++ 代码,本地的 C/C++ 代码也可以调用 java 代码。Java 通过 C/C++ 使用本地的代码的一个关键性原因在于 C/C++ 代码的高效性。

在 Android Studio 下,进行JNI的开发,需要准备以下内容:

(1)Android Studio 2.2以上。

(2)NDK:这套工具集允许为 Android 使用 C 和 C++ 代码。

(3)CMake:一款外部构建工具,可与 Gradle 搭配使用来构建原生库。如果只计划使用 ndk-build,则不需要此组件。

(4LLDB:一种调试程序,Android Studio 使用它来调试原生代码。

创建支持C++的项目

新建支持C++的项目

在新建项目时,勾上 就行了:

在向导的 Customize C++ Support 部分,有下列自定义项目可供选择:

  • C++ Standard:使用下拉列表选择使用哪种 C++ 标准。选择 Toolchain Default 会使用默认的 CMake 设置。
  • Exceptions Support:如果希望启用对 C++ 异常处理的支持,请选中此复选框。如果启用此复选框,Android Studio 会将 -fexceptions 标志添加到模块级 build.gradle文件的 cppFlags中,Gradle 会将其传递到 CMake。
  • Runtime Type Information Support:如果希望支持 RTTI,请选中此复选框。如果启用此复选框,Android Studio 会将 -frtti 标志添加到模块级 build.gradle文件的 cppFlags中,Gradle 会将其传递到 CMake。

支持C++的项目目录

(1)下存放的我们编写供JNI调用的C++源码。

(2)文件是CMake的配置文件,通常他包含的内容如下:

代码语言:javascript
复制
 
 

build.gradle的配置

代码语言:javascript
复制
 
 

注意事项

  • 1.在使用JNI前,需要加载so库
代码语言:javascript
复制
 
 
  • 2.快速生成C++代码:先在java中定义native方法,然后使用 快捷键自动生成C++方法体。
  • 3.CPP 资源文件夹下面的文件和文件夹不能重名,不然 System.loadLibrary() 时找不到,会报错:java.lang.UnsatisfiedLinkError: Native method not found.
  • 4.在定义库的名字时,不要加前缀 lib 和后缀 .so,不然会报错:java.lang.UnsatisfiedLinkError: Couldn’t load xxx : findLibrary【findLibrary returned null错误.
  • 5.新建 C/C++ 源代码文件,要添加到 CMakeLists.txt 文件中。
代码语言:javascript
复制
 
 
  • 6.引入第三方 .so文件,要添加到 CMakeLists.txt 文件中。
代码语言:javascript
复制
 
 
  • 7.引入第三方 .h 文件夹,也要添加到 CMakeLists.txt 文件中
代码语言:javascript
复制
 
 
  • 8.C++ library编译生成的so文件,在 下

至此完成了CMake的设置,下面我们就可以愉快地进行jni开发了!

讲完了两种进行JNI开发的姿势后,下面我们来简单讲讲JNI的基础语法。

JNI基础语法

基础类型

Java类型

native类型

描述

boolean

jboolean

unsigned 8 bits

byte

jbyte

signed 8 bits

char

jchar

unsigned 16 bits

short

jshort

signed 16 bits

int

jint

signed 32 bits

long

jlong

signed 64 bits

float

jfloat

32 bits

double

jdouble

64 bits

void

void

N/A

引用类型

JNI为不同的java对象提供了不同的引用类型,JNI引用类型如下:

在c里面,所有JNI引用类型其实都是jobject。

Native方法参数

  • JNI接口指针是native方法的第一个参数,JNI接口指针的类型是JNIEnv。
  • 第二个参数取决于native method是否静态方法,如果是非静态方法,那么第二个参数是对对象的引用,如果是静态方法,则第二个参数是对它的class类的引用
  • 剩下的参数跟Java方法参数一一对应
代码语言:javascript
复制
 
 

点击查看JNI接口

签名描述

基础数据类型

Java类型

签名描述

boolean

Z

byte

B

char

C

short

S

int

I

long

J

float

F

double

D

void

引用数据类型

(以 开头,以 结束,中间对应的是该类型的完整路径)

代码语言:javascript
复制
 
 

数组

(在类型前面添加 ,几维数组就在前面添加几个 )

代码语言:javascript
复制
java基础类编写
 
 

使用命令查看

代码语言:javascript
复制
 
 

class文件存在于 下。

JNI常见用法

1、jni访问java非静态成员变量

1.使用 、 获取调用对象的类

2.使用 获取字段的ID。这里需要传入字段类型的签名描述。

3.使用 、 等方法,获取字段的值。使用 、 等方法,设置字段的值。

注意:即使字段是 也照样可以正常访问。

代码语言:javascript
复制
 
 

2、jni访问java静态成员变量

1.使用 、 获取调用对象的类

2.使用 获取字段的ID。这里需要传入字段类型的签名描述。

3.使用 、 等方法,获取字段的值。使用 、 等方法,设置字段的值。

3、jni调用java非静态成员方法

1.使用 、 获取调用对象的类

2.使用 获取方法的ID。这里需要传入方法的签名描述。

3.使用 执行无返回值的方法,使用 、 等执行有返回值的方法。

代码语言:javascript
复制
 
 

4、jni调用java静态成员方法

1.使用 、 获取调用对象的类

2.使用 获取方法的ID。这里需要传入方法的签名描述。

3.使用 执行无返回值的方法,使用 、 等执行有返回值的方法。

5、jni调用java构造方法

1.使用 获取需要构造的类

2.使用 获取构造方法的ID。方法名为 , 这里需要传入方法的签名描述。

3.使用 执行创建对象。

代码语言:javascript
复制
 
 

6、jni引用全局变量

1.使用 创建全局引用,使用 创建局部引用。

2.局部引用,通过DeleteLocalRef手动释放对象;全局引用,通过DeleteGlobalRef手动释放对象。

3.引用不主动释放会导致内存泄漏。

7、jni异常处理

1.使用 进行异常的检测。注意,这里只能检测java异常。

2.使用 进行异常的清除。

3.使用 来上抛异常。

注意, 和 一般是成对出现的,类似于java的try-catch。

代码语言:javascript
复制
 
 

8、日志打印

代码语言:javascript
复制

版权声明


相关文章:

  • java基础类的定义2024-11-11 10:58:03
  • 学Kotlin需要Java基础吗2024-11-11 10:58:03
  • java零基础账户取款2024-11-11 10:58:03
  • java最基础教学免费视频2024-11-11 10:58:03
  • java基础总结网站2024-11-11 10:58:03
  • JAVA基础会了自学代码难吗2024-11-11 10:58:03
  • 学了java基础用在哪2024-11-11 10:58:03
  • java实验数据库基础实验2024-11-11 10:58:03
  • java基础认知2024-11-11 10:58:03
  • 杭州java零基础2024-11-11 10:58:03