JNI
*Java native interface
基本数据类型
java
byte:1
short:2
int:4
long:8
float:4
double:8
char:2
boolean:1
C
short:2
int:4
long:4
float:4
double:8
char:1
有符号无符号
无符号表示不分正负
int类型,4个字节,32位,可以表示 2的32次方 个数字
int能表示的最大值是 2的32次方-1 ,那么取值范围就是 0 ~ 2的32次方-1
有符号:最高位取出来作为符号位,表示正负;剩下31位,作为数值位,表示数字
只有31个数值位,那么能表示的数字个数是 2的31次方,取值范围是 0 ~ 2的31次方-1
符号位如果为0,那么数值位表示出来的就是正数,符号位如果为1,那么数值位表示出来的就是负数
符号位为0时,取值范围是 0 ~ 2的31次方-1,符号位为1时,范围是 -2的31次方 ~ -1
两个范围取并集,那么有符号int的范围就是 -2的31次方 ~ 2的31次方-1
无符号数的最高位依然是数值位,没有符号位
无符号int的取值范围是 0 ~ 2的32次方-1
原反补
原码:数字转换成二进制表示
反码:原码除最高位,其他位依次取反
补码:反码 + 1
正数的原反补是相同的
输入函数
每一块内存都有地址,没有地址的内存空间是无法访问的
内存中的所有数据都是通过地址拿到的
C的数组不会检测越界
内存地址
32位操作系统,最大能支持的内存数量是4G
32位系统的地址总线长度是4个字节,也就是说可以分配 2的32次方 个数字作为内存地址
每一个字节都必须有一个内存地址
32位系统能支持的内存是 2的32次方 个字节
内存修改器
原理:找到要修改的变量的地址,直接操作地址上的值
金山游侠、东方魔术师
指针
定义一个int型的指针变量,它的值必须是一个int变量的地址
int* p = &i;
指针常见错误
为赋值的指针,不要去使用*p,这种指针称为野指针
值传递引用传递
所有传递都是值传递,引用传递传的也是一个值,但是这个值是一个地址
堆栈
栈
自动申请
大小是固定的
占用空间是连续的
自动释放
栈上分配的内存叫静态内存
堆
程序员手动申请
java:new
C:malloc
堆的大小受限于系统的虚拟内存
堆占用的空间是不连续的
java:自动回收
C:手动回收
堆上分配的内存叫动态内存
第二天
交叉编译
在一个平台下编译出另一个平台可以执行的二进制文件
不同平台是彼此不兼容的
CPU平台:x86,arm,mips
系统平台:Windows,Linux,Mac os
原理:模拟另一个平台的特性去编译代码
开发工具
NDK:native development kits
CDT:C/C++ development tools
高亮显示C语言关键字
NDK目录
build/tools:存放了大量Linux的批处理文件,用于模拟Linux特性交叉编译
docs:离线帮助文档
platforms:按照Android版本分了若干个文件夹
usr:Unix system resource
include:开发jni会用到的头文件
lib:编译运行C代码时会用到的so动态链接库
按系统平台分了3个文件夹
sample:使用jni的案例
sources:ndk的源码
ndk-build:编译C代码,打包成so类库
JNI流程
在java代码定义本地方法
在项目根目录下创建jni文件夹,文件夹中创建c文件
c文件中定义函数实现java的本地方法
函数的命名要注意返回值、包名、类名本地方法名和方法的参数
在jni文件夹下创建Android.mk文件,配置要编译的c文件是哪一个
编译打包c文件,生成so类库
在java代码中,加载so类库,然后调用本地方法
常见错误
找不到类库
类库名写错了
没有添加相应平台的支持
找不到本地方法
没有加载类库
C函数名写错
javah
生成函数声明
1.7:在src目录下执行javah com.itheima.helloworld2.MainActivity
1.6:在bin/classes目录下执行
添加本地支持
自动创建jni文件夹,文件夹中自动创建cpp文件和Android.mk文件
项目可以指定jni.h头文件的路径
c文件中可以实时编译
项目部署时,自动编译打包出so类库,然后才会部署到手机上
javap
在bin/classes目录下执行javap -s com.itheima.helloworld2.MainActivity
第三天
锅炉压力传感器
本地方法执行在哪个线程,C函数就会执行在那个线程
自定义控件入门
C++实现JNI
预编译
在代码开始编译之前,会先进入预编译阶段,预编译阶段是执行预编译代码
预编译阶段的作用就是决定哪些代码可以进入编译阶段
JNIEnv与C的不一样
函数要先声明,把javah生成的头文件包含进来即可
fork函数
分支一个C进程