Android之JNI开发
JNI
JNI是Java Native Interface的缩写,俗称Java本地接口,是Java语言提供的用于Java和C/C++相互沟通的机制,Java可以通过JNI调用本地的C/C++代码,本地的C/C++的代码也可以通过JNI调用Java代码。
那什么场景下可能会用到JNI呢?
1、需要提升性能时,比如说做一些底层的开发,例如音视频处理之类的,通常都会用到JNI。
2、增加破解难度,例如需要提升代码的保护级别,需要将一些敏感信息放到底层隐藏起来。
3、需要使用到一些较为成熟的底层C/C++库时。
NDK
要在安卓上使用JNI就需要用到NDK,而NDK一系列工具的集合,它提供了一系列的工具帮助开发者快使得C/C++代码能够交叉编译生成可在安卓系统上运行的动态库库或者静态库。例如我们想要将基于C的音视频处理库FFmpeg移植到安卓平台上使用的话就需要用到NDK进行交叉编译。
动态库和静态库
1、静态库
静态库是指在链接阶段,编译器将汇编生成的.o目标文件与库文件一起链接打包到可执行文件中,或者说一起链接生成最后的可执行文件。因此对应的链接方式称为静态链接。
因为静态库是在编译期间连接库文件的,所以静态库存在着可执行文件体积较大,更新维护不方便等问题。
2、动态库
动态库又叫共享库,或动态链接库。动态库在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入,不同的应用程序如果要调用同一个库,在内存中只需要有一份该共享库即可,这样就规避了空间浪费的问题。而且动态库是在程序运行时才被载入,所以相对静态库来说动态库还具有更新、部署方便等优点。
正因为动态库的这些优点,所以目前的大多数的SDK普遍才有动态库的方式。
————————————————
使用Android Studio新建一个Native C++工程
JNIEXPORT
// JNIEXPORT是一个宏,它们在不同的平台有着不同的定义,它的主要作用是保证在本库中声明的方法,能够在其他项目中可以被调用。
例如attribute___((visibility ("default"))) 表示外部可见,类似于public修饰符 (即:可以被外部调用),而attribute___((visibility ("hidden")))表示隐藏,类似于private修饰符 (即:只能被内部调用)。 JNICALL
JNICALL也是一个宏,同样在不同的平台也有着不同的定义,用来表示函数的调用规范(如:__stdcall),目前在linux平台还是是空定义。 函数名
例如:Java_com_fly_jnitest_MainActivity_stringFromJNI
这是一个静态注册的函数名,它是与对于的Java方法有着对应关系的,他们的对应关系是:
Java_<包名>_<类名>_<方法名> JNIEnv
JNIEnv* 是指向JVM函数表的指针,JNIEnv代表了Java环境,通过JNIEnv*就可以对Java端的代码进行操作,例如创建Java对象、访问Java对象方法、获取Java对象的属性等。
总之它是Java方法与C/C++方法沟通的桥梁。 需要注意的是:一个JNIEnv指针仅在其相关联的线程中有效。不能将这个指针从一个线程中传递给另一个线程,或者在多线程中缓存和使用它。Java虚拟机在同一个线程传递给本地方法相同的JNIEnv指针,但是从不同线程中调用本地方法时传递的是不同的JNIEnv指针
数据类型映射关系
在JNI中每种Java的基本数据类型都与C/C++的基本数据类型形成映射关系。
下图展示的是Java中的基本数据类型与JNI中的基本数据类型的映射关系:

[使用]
[开发]
安卓开发需要依赖NDK, 需要再Ndk Tools中包含 NDK 和CMake

1) 需要在cpp目录下,新建C文件,例如Utils.c
#include <jni.h>
JNIEXPORT jint
JNICALL Java_com_lanlang_demo_Utils_v1(JNIEnv *env, jclass clazz,jint v1,jint v2) {
return v1+v2;
}
2)在Java下新建一个类,编写静态方法
package com.justin.s8day12;
public class Utils {
static {
System.loadLibrary("utils");
}
public static native int v1(int a1,int a2); }
3) 引入静态文件
static {
System.loadLibrary("utils");
}
4)在CMakeLists.txt中加入编写的c文件
add_library(
utils # 起个名字,我们叫utils
SHARED
# 指定我们新建的c文件
utils.c)
target_link_libraries(
utils# 加入我们自己写的utils,空格分割,写多个
${log-lib})
5) 在Java代码中调用
tv.setText(String.valueOf(Utils.v1(33,44)));
编译打包完成之后,逆向流程:
-使用压缩工具把 apk解压
-进入lib的arm64-v8a目录,看到so文件
-把so文件拖动到IDA中
-选择exports导出
-双击函数名,看到汇编
-按F5,把混编进行反编译
Java中类文件的加载与实际文件的关系:
# System.loadLibrary("dynamic"); -->libdynamic.so
# System.loadLibrary("utils"); -->libutils.so
一般都是会加上lib的前缀
注册方式:
静态注册:
反编译自己app----》找到了jni调用位置---》通过System.loadLibrary("utils")---》确定是哪个so文件---》去so文件中,通过 静态注册方案找
动态注册:
反编译so后,找JNI_OnLoad
Android之JNI开发的更多相关文章
- Android Studio JNI开发入门教程
Android Studio JNI开发入门教程 2016-08-29 14:38 3269人阅读 评论(0) 收藏 举报 分类: JNI(3) 目录(?)[+] 概述 在Andorid ...
- android下JNI开发
android下JNI开发 what 什么是JNI JNI java native interface native本地 java本地接口 通过JNI可以实现java和本地代码之间相互调用 jni可以 ...
- Android的JNI开发
变量的定义 int i; typedef int x;//定义一个int x数据类型 x a=10; printf("size=%d",sizeof(i));//获取int类型长度 ...
- Android Studio JNI 开发简单案例
转载:http://www.androidchina.net/5744.html 进程保活,热修复,硬件接入等等都需要底层的支持,而底层代码是 C .C++ 写的,那么在 Android 中怎么调用底 ...
- 实现Android Studio JNI开发C/C++使用__android_log_print输出Log
相信很多人在刚开始学习Android JNI编程的时候,需要输出Log,在百度Google搜索的时候都是说需要在Android.mk中加入LOCAL_LDLIBS+= -L$(SYSROOT)/usr ...
- NDK工具开发Jni,Android studio jni开发
NDK工具开发JNI 对于JNI的作用,我这边就不详细说明了,百度google 有很多这样的介绍,这边着重详解AS使用NDK工具开发,调C的流程. 1,创建工程 2,创建native方法 //该类的路 ...
- Android游戏开发实践(1)之NDK与JNI开发03
Android游戏开发实践(1)之NDK与JNI开发03 前面已经分享了两篇有关Android平台NDK与JNI开发相关的内容.以下列举前面两篇的链接地址,感兴趣的可以再回顾下.那么,这篇继续这个小专 ...
- Android游戏开发实践(1)之NDK与JNI开发01
Android游戏开发实践(1)之NDK与JNI开发01 NDK是Native Developement Kit的缩写,顾名思义,NDK是Google提供的一套原生Java代码与本地C/C++代码&q ...
- Android游戏开发实践(1)之NDK与JNI开发02
Android游戏开发实践(1)之NDK与JNI开发02 承接上篇Android游戏开发实践(1)之NDK与JNI开发01分享完JNI的基础和简要开发流程之后,再来分享下在Android环境下的JNI ...
- android JNI开发
1.NDK简介 NDK(Native Development Kit)NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk.NDK集成了交叉 ...
随机推荐
- SciPy从入门到放弃
目录 SciPy简介 拟合与优化模块 求最小值 曲线拟合 线性代数模块 统计模块 直方图和概率密度函数 统计检验 SciPy简介 SciPy是一种以NumPy为基础,用于数学.工程及许多其他的科学任务 ...
- MyBatis 从入门到放弃 ( MyBatis基础总结 )
目录 MyBatis历史 Mybatis特性 MyBatis下载 和其它持久化层技术对比 开发环境 创建maven工程 创建MyBatis的核心配置文件 创建mapper接口 创建MyBatis的映射 ...
- CLion 2022.2.4破解教程详细图解mac,windows,linux均适用
下载与安装 此教程为CLion 2022.2.4 破解教程,且此教程以及下面提供的破解补丁适用与2022.2以后的新版本. 2022年11月10日亲测有效,mac与windows均测试完美破解 CLi ...
- 【YashanDB知识库】绑定参数,同一个sql多个执行计划的问题
问题现象 同一个sql有两个执行计划,是否合理? 它的EXECUTIONS,ELAPSED_TIME等统计信息怎么看,是独立分开的还是统一计算的? 如下图: 问题影响版本 tpcc测试:23.2.1. ...
- 8.4linux定时任务-环境变量-数据库
配合SUID本地环境变量提权 思路原理:利用sh环境变量替换,使得/tmp/ps得到root权限:ps=sh 过程:手写调用文件-编译-复制文件-增加环境变量-执行 gcc demon1.c -o s ...
- linux磁盘分区之后,lsblk没有显示
可以看出 fdisk 创建一个 sda4 的分区 并保存退出, 但是 不管是使用 fdisk -l ,还是 lsblk 都无法显示出来, 那么导致问题的原因,主要是因为新创建了分区之后,系统没有重 ...
- 内网渗透-Windows常用提权方法
一.前言 将介绍常见的提权方法.从为什么该方法能够提权(原理)到使用方法. 二.系统内核漏洞提权 1.为什么能提权? 内核漏洞通常是指内核溢出漏洞,什么溢出呢?缓冲区溢出. 那什么是缓冲区溢出呢?当应 ...
- SQL limit字句
limit用法介绍 limit子句可以返回检索查询行的某一连续的部分 用法介绍: SELECT column_list FROM table1 ORDER BY column_list LIMIT r ...
- 【赵渝强老师】Docker的日志
Docker的日志分两类,一类是 Docker引擎的日志:另一类是容器日志.下面我们分别进行介绍. 一.Docker引擎的日志 Docker 引擎日志 一般是交给了 Upstart(Ubuntu 14 ...
- 活动预告 | 中国数据库联盟(ACDU)中国行定档深圳,一起揭秘数据库前沿技术
在当今数字化时代,数据库是各行各业中最核心的信息管理系统之一.随着技术的飞速发展,数据库领域也不断涌现出新的前沿技术和创新应用.数据库运维和开发人员需要紧跟前沿技术,才能保持竞争力,并实现更高效.更智 ...