手记

jni笔记

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流程

  1. 在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进程

原文链接:http://www.apkbus.com/blog-851511-63504.html

0人推荐
随时随地看视频
慕课网APP