Android下JNI开发

【Android JNI 开发入门指南】 交叉编译]在一个平台上去编译另一个平台上可以执行的本地代码。交叉编译的实现原理: 模拟不同平台的特性去编译代码。Android系统运行的 CPU 架构 :ARM,X86,mips[NDK (native Develop Kit),谷歌提供的: 用作JNI开发的交叉编译工具集。△安装介绍;如果电脑与JDK都是32位的则选择 android-ndk-r9d-windows-x86 的开发工具包。64为的则选择 android-ndk-r9d-windows-x86_64 的开发工具包。 阅读详情

什么是JNI

  • JNI java native interface native本地 java本地接口

  • 通过JNI可以实现java和本地代码之间相互调用

  • jni可以看做是翻译 实际上就是一套协议

为什么要用JNI

  1. 市场需求

  2. 让java代码和底层代码之间互相调用

  • java调用底层特殊硬件(调用c语言,车载电脑)

  • 效率上c/c++语言效率更高(时间和内存要求严格的场景)

  • 复用已经存在的c代码, c语言发展了几十年有很多优秀的代码库(ffmpeg,opencv,7zip)

  • java反编译非常容易.c语言反编译不容易.关键业务逻辑需要用c实现.

  • 历史遗留问题,复用原来pc端的c代码

怎么用JNI

  • 熟悉java

  • c/c++ 能看懂 会调用(2级等级考试程度)

  • JNI规范(开发流程 NDK native develop kit)

实际应用场景 (只要是和硬件打交道,必定涉及到驱动,物联网)

开发环境搭建

C基本语法

CHelloWorld

#include<stdio.h>    // 相当于 java的import .h c的头文件 stdio.h standard io 标准输入输出 
#include<stdlib.h>   // stdlib standard library 标准函数库    java.lang 
/**
*/
main(){    // public static void main(String[] args)
       printf("helloworld!\n");  //System.out.println();   "\n"换行符 
       system("javac Hello.java");
       system("java Hello");
       system("notepad");
       system("pause"); //system执行windows的系统命令 
       } 

C的基本数据类型

  • java基本数据类型

  • boolean 1

  • byte 1

  • char 2

  • short 2

  • int 4

  • long 8

  • float 4

  • double 8

演示不同类型所占用的字节数

  • c基本数据类型

  • char 1个字节

  • short 2

  • int 4

  • long 4

  • float 4

  • double 8

  • void 1

  • c的基本类型char, int, float, double, long, short, signed, unsigned, void

总结:

  • c语言中的char可以用java的byte代替

  • c语言中的int ,float , double ,short 和java完全一样,可以相互代替

  • c语言的long ,用java的int代替

  • java中的byte和boolean类型,c语言里面没有.

  • java中的byte可以用c语言中的char表示

  • java中的boolean类型,c语言用0 false和非0 true

  • java中的long类型,c语言用 long long类型表示.

signed,unsigned 只能修饰整形

C的输出函数


%d  -  int
%ld – long int
%lld - long long
%hd – 短整型
%c  - char
%f -  float
%lf – double
%u – 无符号数
%x – 十六进制输出 int 或者long int 或者short int
%o -  八进制输出
%s – 字符串

16进制和8进制表示方法

  • C字符串

    • C没有String类型 C的字符串实际就是字符数组

    • C数组定义 [ ]只能再变量名之后

    • C字符串两种定义方式

      char str[] = {'h','e','l','l','o','\0'};//注意'\0'字符串结束符

      
      char str[] = "你好"; //这种定义方式不用写结束符 可以表示汉字

C的输入函数

输入一个班级的人数

输入一个班级的名称

注意数组越界

  • scanf("占位符", &地址);

  • & 取地址符

  • C字符串不检查下标越界 使用时要注意

指针入门

指针就是一个地址,地址就是一个指针

QQ连连看

指针变量:用来存放一个地址的变量.用来存储某种数据在内存中的地址.

如果一个* 在指针变量的前面,代表的含义就是把这个地址里面的数据取出来

*号的三种含义

* 号的第一种含义表示的是乘法操作.


int i = 3;
int j = 5;
i * j相乘

* 号的第二种含义


如果一个星号是在一种数据类型的后面
代表的就是这种数据类型的指针变量,
用来存放这种数据类型在内存中的地址.
int i = 3;
int*  p; 可以存放i的地址
p=&i;

* 号的第三种含义


如果星号在一个指针变量的前面
代表的就是把这个地址里面的数据取出来.
int*  p;    
*p; 把p地址里面的数据取出来

  • 画图分析指针和地址间的关系

  • 指针常见错误

    • 声明了指针变量后 未初始化直接通过*p 进行赋值操作

        • 未赋值的指针称为野指针

    • 指针类型错误 如int* p 指向了double类型的地址, 通过指针进行读取操作时,读取值会出错

内存地址的概念

  • 声明一个变量,就会立即为这个变量申请内存,一定会有一个对应的内存地址

  • 没有地址的内存是无法使用的

  • 内存的每一个字节都有一个对应的地址

  • 内存地址用一个16进制数来表示

  • 32位操作系统最大可以支持4G内存

    • 32位系统的地址总线为32位,也就是说系统有2^32个数字可以分配给内存作为地址使用

指针的练习

  • 交换两个变量值的最基本写法

  • 把前面交换值的逻辑抽取一个方法去写,发现值没有发生变化

  • 换成Java代码,在eclpse运行,值还是没有发生交换

  • 在Java中,以下面的方式交换数据可以交换

  • 传递失败的原因是子函数所申请的内存空间,在子涵数运行完毕后,全部释放

  • 将普通的值传递改为引用传递后能够改变值.

  • 画图分析通过传地址后值交换的过程(Java里面对象传递,实际上是引用传递,也就是地址传递)

  • 值传递和引用传递(交换两个数的值)

    • 引用传递本质是把地址传递过去

    • 所有传递其实本质都是值传递,引用传递其实也是传递一个值,但是这个值是一个内存地址

      void swap(int* p, int* p2){

      
          int temp = *p;
          *p = *p2;
          *p2 = temp; 
      }
      main(){
          int i = 123;
          int j = 456;
          //将i, j的地址传递过去
          swap(&i,&j);
          printf("i = %d, j = %d", i, j);
      }
  • 看代码区分是java程序员还是C程序员写代码(google工程师很多的android程序员都是由C程序员转过来的,从代码中就能看到C语言的特性,函数运行完毕没有返回值,一般是C语言的特点).也就是把地址作为参数传入函数中,当函数执行完毕时,参数的值就已经被修改了

  • 返回多个值

    • 把地址作为参数传入函数中,当函数执行完毕时,参数的值就已经被修改了

多级指针

  • int* p; int 类型的一级指针 int** p2; int 类型的二级指针

  • 二级指针变量只能保存一级指针变量的地址

  • 有几个* 就是几级指针 int*** 三级指针

  • 通过int类型三级指针 操作int类型变量的值 ***p

    int i = 123;

    
        //int类型一级指针 
        int* p = &i;
        //int 类型 二级指针 二级指针只能保存一级指针的地址 
        int** p2 = &p;
        //int 类型 三级指针  三级指针只能保存二级指针的地址 
        int*** p3 = &p2;
        //通过p3 取出 i的值
        printf("***p3 = %d\n", ***p3);
  • 多级指针案例 取出子函数中临时变量的地址(在主函数中取出子函数中一级指针中变量的地址值)

  • 画图讲解内存地址的赋值过程

*幻影数据,旧数据,无效数据(将内存条放入液氮中,可以将旧数据取出)

数组和指针的关系

  • 打印数组中的第0个元素,注意[]放的位置

  • C语言中的数组不检查是否越界,所以一旦给一个越界的索引,获取的是随机的值

  • 创建一个子函数,专门用来打印数组,在子函数中,确定索引的下标,防止数组越界

  • 数组占用的内存空间是连续的

  • 数组变量保存的是第0个元素地址,也就是首地址

  • int数组在内存中的的地址.每个元素相隔4位,因为每一个int值占四位(也就是说每个元素占据的byte的内存空间,跟数组的数据类型有关)

  • *(p + 1):指针位移一个单位,一个单位是多少个字节,取决于指针的类型

指针的长度

  • 不管变量的类型是什么,它的内存地址的长度一定是相同的

  • 内存地址不能相减

  • 所有的语言,如果需要执行,都必须先被装载在内存中,所有不同的类型只决定变量占用的内存空间不同

  • 32位环境下,内存地址长度都是4个字节,所以指针变量长度只需4个字节即可


  • 区分指针类型是为了指针位移运算方便

堆栈概念 静态内存分配 动态内存分配

  • 栈内存

    • 系统自动分配

    • 系统自动销毁

    • 连续的内存区域

    • 向低地址扩展

    • 大小固定

    • 栈上分配的内存称为静态内存

  • 静态内存分配

  • 子函数执行完,子函数中的所有局部变量都会被销毁,内存释放,但内存地址不可能被销毁,只是地址上的值没了

  • 堆内存

    • 程序员手动分配

      • java:new

      • c:malloc

    • 空间不连续

    • 大小取决于系统的虚拟内存

    • C:程序员手动回收free

    • java:自动回收

    • 堆上分配的内存称为动态内存

  • C语言版本学生管理系统,通过申请内存,动态申请内存

    • 申请固定的内存大小

    • 追加申请更多内存

  • 多级指针取变量值(如何取到 i的值)

  • 多级指针在Java中的应用举例(开发一款网游游戏)

结构体(类似java中的类,把一些方法和数据封装在一起,这个时候就有了一个种结构体的出现,结构体是java类的老祖宗,java中的类就是由C语言中的结构体演化过来的,结构体的使用,基本上和java中的类的使用一样)

  • 定义一个简单结构体

  • 使用结构体,调用结构体

  • 结构体中的属性长度会被自动补齐,这是为了方便指针位移运算(这个是编译器内部做的处理)

  • 结构体中不能定义函数

*结构体中可以声明一个函数

*结构体中使用函数方法1

*结构体中使用函数方法2

*结构体中使用函数方法3

  • 提高可读性,名字最好相同

  • 程序运行时,函数也是保存在内存中的,也有一个地址

  • 结构体中只能定义变量

  • 函数指针其实也是变量,它是指针变量

  • 函数指针的定义 返回值类型(*变量名)(接收的参数);

  • 函数指针的赋值: 函数指针只能指向跟它返回值和接收的参数相同的函数

联合体(类似java中的泛型,可以表示多钟类型)

  • 长度等于联合体中定义的变量当中最长的那个

枚举(和java中的枚举使用一模一样)


  #include <stdio.h>
 enum WeekDay
  {
  Monday=8,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
  };
  
  main(void)
  {
    //int day;
   enum WeekDay day = Sunday;
   printf("%d\n",day);
   system("pause");
   return 0;
 }

类型定义(自定义类型),就是给类型取别名,注意格式!


安卓 jni 开发 —— Android Studio 打包 so 的坑 阅读详情

相关推荐

Android Studio开发JNI示例

JNI和NDK介绍 JNI(Java Native Interface),是方便Java调用C、C++等Native代码所封装的一层接口,相当于一座桥梁。通过JNI可以操作一些Java无法完成的与系统相关的特性,尤其在图像和视频处理中大量用到。 NDK(Native Development Kit)是Google提供的一套工具,其中一个特性是提供了交叉编译,即C或者C++不是跨平台的,但通过N...

wzhseu的博客 3万+

Android JNI开发深度学习

在基本了解JIN后,如您对JNI进阶学习感兴趣,请阅读本篇博文,帮助您进一步深入学习JNI函数开发。该篇博文从JNI的原理、函数创建及规则、Java与C/C++互调操作、JNI开发的各细则进行详细说明分析,希望能帮助大家能够快速熟练JNI的开发。

luo_boke的博客 7735

配电变压器测控终端装置设计

配电变压器测控终端装置在电网运行中承担着数据采集、状态监测、故障预警及远程控制的关键任务,其性能直接关系到配电系统的安全性与可靠性。本研究围绕测控终端的硬件电路、软件算法、通信系统及系统优化展开深入分析,并基于实验测试验证系统性能。硬件设计包括模拟量输入电路、电压电流信号变换电路、A/D转换电路、控制与通信电路及系统电源电路,确保信号采集的高精度与系统的稳定性。软件部分涵盖系统控制程序、数据采集与处理程序、通信程序及显示与控制程序,实现数据的实时处理与传输。通信模块结合RS-485、CAN总线及以太网技术,

weixin_44553616的博客 1103

Android JNI 开发

①:NDK与JNI简介 NDK:Native Development Kit,是Android的一种开发工具包,能够快速开发C,C++的动态库,并自动将so和应用打包成APK。而NDK的使用场景就是通过NDK在Android中使用JNI。 JNI:Java Native Interface的缩写,即Java的本地接口,JNI可以使得Java与C,C++语言进行交互。 NDK优点: 1.APK的Java层代码很容易被反编译,而C/C++库反编译难度较大 2.将要求高性能的应用逻辑使用C开发,从而提高

qq_37565670的博客 3197

医疗领域BGE-M3模型微调全流程:从数据准备到效果评估

本文详细介绍了医疗领域BGE-M3模型的微调全流程,从数据准备到效果评估。通过医疗数据微调,BGE-M3模型在临床问答、病历检索等场景中表现显著提升,能够准确理解医学术语之间的细微差别。文章还提供了实战练习代码和效果评估指标,帮助开发者快速掌握医疗文本嵌入模型的应用技巧。

weixin_29098367的博客 282

BLE天线设计避坑:NRF52832官方50欧姆阻抗匹配的3个常见误区

本文深入解析NRF52832蓝牙SoC天线设计中的常见误区,重点探讨50欧姆阻抗匹配的3个关键问题:PCB板材介电常数差异、匹配元件寄生参数及VSWR测试。通过实测数据和优化方案,帮助工程师规避设计陷阱,提升BLE通信性能。

beer8的博客 214

Android开发——JNI开发

JNI不是Android特有的,是通用的。用于Java与C++(C)层代码的相互调用。Java是解释型语言,虽然JVM经过了很多优化,性能大大提高,但是始终比不上C++这种编译型语言。从Android架构来看,framework层为Java语言编写,但是很多实际运行的却是在Native层(C\C++语言编写)。

一切皆是定数的博客 1312

Kalibr标定避坑指南:如何用AprilGrid板快速完成双目IMU标定

本文详细介绍了使用AprilGrid板进行Kalibr双目IMU联合标定的实战技巧,包括标定工具选型、数据采集优化、标定流程及结果验证。通过AprilGrid板的唯一标识性和抗遮挡优势,结合IMU静止标定和运动激励设计,显著提升标定精度。文章还提供了常见报错处理和高级优化技巧,帮助开发者高效完成传感器标定。

sunny的博客 282

Android JNI开发从0到1,java调C,C调Java,保姆级教程详解

第三歩,在app目录下的build.gradle文件中的,android{}闭包中,指定CMakeLists.txt路径。2.根据命令行javah +JNI2的全类名,生成com_example_jniproject_JNI2.h头文件。在app目录下,指定CmakeLists.txt文件,根据注释进行相应添加。3.根据jni协议,去写对应的c代码,创建Test.c文件,代码如下。2.根据命令行,javah +JNI3全类名,生成对应的头文件。第五步,C代码调用Java代码,首先创建JNI3.java。

路宇的博客 2658

【无人机路径规划】基于强化学习实现多无人机路径规划

【无人机路径规划】基于强化学习实现多无人机路径规划

k8291121的博客 1656

Android AMS——AMS初始化(二)

Android AMS 也是一个系统服务,属于系统服务中的引导服务,在 startBootstrapServices() 方法中启动。这里我们就来看一下 ActivityManagerService 的启动流程。

小旭的专栏 779

安卓开发-JNI

JNI(Java Native Interface)是Java本地接口,它允许Java代码和其他语言(通常是C或C++)编写的代码进行交互。JNI的作用是让Java程序能够调用和被C/C++程序调用,从而实现Java与本地代码的互操作性。NDK的主要目的是让开发者能够利用C/C++的性能优势,开发高性能的Android应用。JNI允许Java代码调用C/C++代码,也可以让C/C++代码调用Java代码。静态注册是通过在C++代码中直接实现JNI方法来完成的。动态注册是通过在C++代码中调用。

qq_62784677的博客 1172

人群仿真软件:Pathfinder_(14).与其他软件的集成与互操作

在人群仿真软件的二次开发中,与其他软件的集成和互操作是非常重要的。通过数据导入导出、接口调用和脚本编写,可以显著提升仿真的准确性和实用性。Pathfinder提供了多种数据格式的支持和丰富的API,使得与其他软件的集成变得简单高效。无论是建筑模型的导入、仿真结果的导出,还是实时数据的交换,Pathfinder都能满足用户的需求。

kkchenjj的博客 1017

JNI 开发基础篇:Android开发中os文件的探索

正题: android开发中,时长会遇到os文件的使用,那么os文件到底是什么?在这篇文章中会进行说明。 .os文件在android中意味着C语言书写的方法,经android提供的ndk进行编译,从而供android方法调用,实现业务需求。 由于android使用的是java语言,无法直接调用C语言函数。同理,C也无法直接使用java语言。但是C可以操作驱动,硬件等。所以android支持C语...

weixin_33743703的博客 122

OpenOCD入门到精通:第28章 综合实战:RISC-V 调试

RISC-V调试实战摘要 本文介绍了RISC-V调试规范及其在OpenOCD中的实现。主要内容包括: RISC-V Debug规范的两个版本(0.11和0.13)及其差异,OpenOCD通过自动检测DTMCS寄存器版本号选择对应驱动实现。 RISC-V调试架构的分层设计,包含DTM、Debug Module、Program Buffer等核心组件,以及三种内存访问方式(progbuf、sysbus、abstract)。 以GD32VF103为例的实战调试配置,包括硬件连接、OpenOCD配置文件编写和GDB

从事嵌入式linux android驱动开发,拥有全栈能力 282

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

[jni] [android] 用C++开发安卓程序

原理 原理其实很简单 首先用FindClass()查找java类,然后用GetMethodID()得到构造函数 构造函数的函数名是“< init >”,返回类型为"V"(void) 最后直接用NewObject()创建一个按钮 回调部分受到了别人文章和快写代码的启发,把回调类的地址传递到java中,java类接收到事件后用地址作为参数调用本地方法,本地方法把地址转换为c++回调类,调用方法 代码 MainActivity.java package com.Diamond.ndk; impor

qq_53530146的博客 5655

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

android java代码打印系统日志_迅为开发板安卓JNI开发实战教程之仿写JNI 代码

转自迅为开发板安卓JNI开发指南硬件平台:迅为iTOP-412开发板B站搜索:北京迅为,免费观看同步视频教程接下来我们来仿写一个这个方法,我们已打开 led 灯代码为例。1. 我们先在 MainActivity 里面实现三个方法,分别对应打开,关闭,和控制,我们添加以下代码:public native int LedOpen();public native int LedClos();public...

weixin_30212009的博客 211

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

[安卓开发笔记二]android Studio通过jni调用C++代码

[安卓开发笔记二]android Studio通过jni调用C++代码 自己需要用到android studio开发安卓项目,为了效率需要用jni来调用C++底层代码,网上关于这方面的资源十分匮乏,自己踩了很多坑,总算明白android studio是如何进行jni的调用,记录与此,贡献自己的一点力量,让后来人少踩坑 1、开发ide:操作系统win7或者mac均可,这点没有关系哈 androi

u012341163的博客 1万+

Android Studio JNI开发入门教程

概述 在Andorid Studio不支持JNI开发之前大家一般都是使用Eclipse开发JNI,各种配置让人觉得很蛋疼。从Andorid Studio支持JNI开发后,让我们开发JNI变的如此简单。下面我就介绍一下Android Studio开发JNI的全过程,如有不对的地方大家批评指正。 你将学习到什么 什么是NDK和JNI为什么要用JNI做开发如何使用Android Studio开

easyer2012的专栏 1万+

Android JNI开发

1. 在Android Studio开发JNI Android Studio第一个JNI开发入门(整理一)_sevenjoin的博客-优快云博客_androidstudio jni开发 Android配置NDK并编译JNI文件做so库_u013214588的博客-优快云博客_android jni编译so android log 封装 #include <android/log.h> #ifndef LOG_TAG #define LOG_TAG "XXXX" #defi

xiaolifeidaofirst的博客 3836

安卓逆向_15( 三 ) --- Android NDK 开发【 jni 静态注册、JNI_OnLoad 动态注册】

Android Studio开发JNI示例:https://blog.youkuaiyun.com/wzhseu/article/details/79683045 JNI_动态注册_静态注册.zip :https://pan.baidu.com/s/1wpTYA9euSdPqE1Z2bA_BHA 提取码: 7h97 错误: 编码GBK的不可映射字符 (ht...

墨鱼菜鸡 641
上一篇: Android面试题
下一篇: Android--内存溢出处理
yipeng95
博客等级 码龄9年 0粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值