JNI

JNI 和 NDK 介绍

夙愿已清 提交于 2020-02-05 02:59:49
1、JNI Java Native Interface(JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI 是本地编程接口,它使得在 Java 虚拟机(VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++ 和汇编语言)编写的应用程序和库进行交互操作。 上面过程分为2个部分: 第一、用C语言生成一个库文件。 第二、在java中调用这个库文件的函数。 JNI 是Java调用Native机制,是Java语言自己的特性,类似的还有微软.Net Framework上的p/invoke,可以让C#或Visual Basic.Net调用C/C++的API,所以说 JNI和Android没有关系 ,在PC上开发Java的应用,如果运行在Windows平台使用 JNI是是经常的,比如说读写Windows的注册表。 2、NDK Native Development Kit(NDK) 是一系列工具的集合。 * NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库。 * NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。 * NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。 NDK

Android NDK开发入门实例

不羁岁月 提交于 2020-02-05 02:48:01
AndroidNDK是能使Android应用开发者把从c/c++编译而来的本地代码嵌入到应用包中的一系列工具的组合。 注意 : AndroidNDK 只能用于 Android1.5 及以上版本中。 I. Android NDK 目标: Android虚拟机允许你的应用在源码中通过JNI调用本地代码(c/c++)中实现的方法们。概括起来,这表示: --你的应用的java源代码中要声明一个或多个方法,这些方法前面需有'native'关键字,这表明它们被本地代码实现。如: [java] view plain copy native byte[] loadFile(String filePath); --你必须提供本地的共享库(.so),库中包含这些方法的实现。这个库将会打包你的应用的.apk中。这个库的命名必须符合标准的Unix命名规则,也就是:lib<something>.so这种形式。并且还要包含一个标准的JNI入口。例如: libFileLoader.so --你的应用必须显式的加载本地库。例如,要在应用启动时加载,只需简单地在代码中增加如下语句: [java] view plain copy static{ System.loadLibrary( "FileLoader"); } 注意写库的名字时你不需要使用 'lib' 前缀和 '.so' 后缀。

Android:NDK开发入门

北城余情 提交于 2020-02-05 02:42:51
为何要用到NDK? 概括来说主要分为以下几种情况: 1. 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。 2. 在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C++代码编写的。 3. 便于移植,用C/C++写得库可以方便在其他的嵌入式平台上再次使用。 下面就介绍下Android NDK的入门学习过程: 入门的最好办法就是学习Android自带的例子, 这里就通过学习Android的NDK自带的demo程序:hello-jni来达到这个目的。 一、 开发环境的搭建 android的NDK开发需要在linux下进行: 因为需要把C/C++编写的代码生成能在arm上运行的.so文件,这就需要用到交叉编译环境,而交叉编译需要在linux系统下才能完成。 安装android-ndk开发包,这个开发包可以在google android 官网下载: 通过这个开发包的工具才能将android jni 的C/C++的代码编译成库 android应用程序开发环境: 包括eclipse、java、 android sdk、 adt等。 如何下载和安装android-ndk我这里就不啰嗦了,安装完之后,需要将android-ndk的路劲加到环境变量PATH中: sudo gedit /etc/environment

java中对native的认识(JNI)

喜夏-厌秋 提交于 2020-01-27 13:22:00
Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。   可以将native方法比作Java程序同C程序的接口,其实现步骤:   1、在Java中声明native()方法,然后编译;   2、用javah产生一个.h文件;   3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);   4、将第三步的.cpp文件编译成动态链接库文件;   5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。   JAVA本地方法适用的情况   1.为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问   2.为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的   3.为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。   首先写好JAVA文件   /*   * Created on 2005-12-19 Author shaoqi   */   package com.hode.hodeframework.modelupdate;  

android jni动态注册

我们两清 提交于 2020-01-27 06:47:22
题外话 转眼间2019年也已经接近尾声了,回顾这一年也发生了很多事,换工作、搬家、赶项目、学习新技术等等很多事,忙碌的一年,博客也被放下了,真的是越来越懒了,每次都有一万个不写博客的理由,之前每年至少还要更新几篇文章,然而今年一篇文章也没写,趁着这个周末没事情,抓住2019年的小尾巴,把自己一直想写的文章写了,于是就有了今天这篇文章。 jni简介 JNI是Java Native Interface的缩写,它提供了若干的接口实现了Java和其他语言的通信(主要是c、c++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。jni是Android中java和c++之间连接的桥梁,jni是jvm提供的一种与native方法对接的方式。 jni的注册方式分为静态注册和动态注册两种, 之前有一篇文章 写过jni相关的知识,那篇文章介绍的关于jni的知识就是静态注册的方式,今天主要写的是jni的动态注册。静态注册和动态注册, 两者优缺点如下: 静态注册 优点: 理解和使用方式简单, 属于傻瓜式操作, 使用相关工具按流程操作就行, 出错率低 缺点: 当需要更改类名,包名或者方法时, 需要按照之前方法重新生成头文件, 灵活性不高 动态注册 优点: 灵活性高, 更改类名,包名或方法时, 只需对更改模块进行少量修改, 效率高 缺点:

JNI(C/C++与java的相互调用)

◇◆丶佛笑我妖孽 提交于 2020-01-23 01:07:05
java调用本地C/C++(native方法) 静态关联 package org.ngb.media; ... static native void start(int var0); 对应JNI方法 JNIEXPORT void JNICALL Java_org_ngb_media_MediaManager_start(JNIEnv *env,jclass cls, jint player){ ......//逻辑代码 } //JNIEnv *env java的环境变量,可以对java端进行操作 JNIEnv类中有很多函数可以用: NewObject:创建Java类中的对象 NewString:创建Java类中的String对象 New<Type>Array:创建类型为Type的数组对象 Get<Type>Field:获取类型为Type的字段 Set<Type>Field:设置类型为Type的字段的值 GetStatic<Type>Field:获取类型为Type的static的字段 SetStatic<Type>Field:设置类型为Type的static的字段的值 Call<Type>Method:调用返回类型为Type的方法 CallStatic<Type>Method:调用返回值类型为Type的static方法 //jclass cls 代表这个本地方法的实例或者这个类本身

【性能调优】JNI内存溢出案例(String对象溢出)

亡梦爱人 提交于 2020-01-19 21:31:05
前言 场景:C++通过JNI将数据传输给Java程序 问题:运行一段时间String对象和Char字符不停变大,直到内存溢出(JVM-OOM) 1 过程 Jmap初步分析头部对象内存占用 PS:jmap -histo:live <pid>,执行该方法会同步执行一次GC,所以,展示的都是无法GC的对象。 发现:String对象有28万个,可能存在String对象被长期持有的现象,初步怀疑是HashMap等缓存持有 Jmap导出堆栈分析:导出堆栈时String对象是21万个 jmap -dump:live,format=b,file=/root/edr.bin 17994 用eclipse-mat打开堆栈文件:通过Histogram看看对象实例数 发现:String对象确实是21万个 看看String对象来自于哪里,并将String列表按RetainedHeap倒叙排列 发现:String对象是来自于本地JNI线程,且这个JNI线程还持有大量的内存 查看程序线程内存占用情况 发现:存在10个相似的线程,都占用了很多内存,且线程类型还是守护类型,但是无法通过线程名判断是什么线程对象 查看线程持有哪些对象 发现:线程持有14759个String对象,基本可以判断是该类(10个)线程没有将JNI-String内存释放 最终确认确实是C++JNI相关代码没有释放内存 2 总结

Android的JNI开发涉及的char和string之间的互相转换

人走茶凉 提交于 2020-01-18 05:38:49
在jni中使用env是有两种情况的,c语言和c++语言。 .c是c语言的源程序格式,.cpp是c++语言的源程序格式。这是两种不同的语言。 C语言互相转换版本: framework/base/services/core/jni 下面是c++语言 system/core/drmservice 下面是c语言 //将char类型转换成jstring类型 jstring CStr2Jstring( JNIEnv* env,const char* str ) { jsize len = strlen(str); // 定义java String类 strClass jclass strClass = (*env)->FindClass(env, "java/lang/String"); //设置String, 保存语言类型,用于byte数组转换至String时的参数 jstring encoding = (*env)->NewStringUTF(env, "GB2312"); // 获取java String类方法String(byte[],String)的构造器,用于将本地byte[]数组转换为一个新String jmethodID ctorID = (*env)->GetMethodID(env, strClass, "<init>", "([BLjava/lang/String;)V"

IDA F5堆栈不平衡的处理

↘锁芯ラ 提交于 2020-01-17 08:00:59
IDA F5堆栈不平衡的处理 1.引出问题 F5时出现如图错误,一般是程序代码有一些干扰代码,让IDA的反汇编分析出现错误。比如用push + n条指令 + retn来实际跳转,而IDA会以为retn是函数要结束,结果它分析后发现调用栈不平衡,因此就提示sp analysis failed. 我们选择抖音老版本的libcms.so作为分析案例,假设Java代码如下 static { System.loadLibrary("cms"); } public native int getUserInfo(); 我们想要分析getUserInfo这个函数,函数被声明为native,这代表了它是一个native方法,真正的代码逻辑由C/C++等native语言实现,它来自名为cms的库,由静态代码块中的System.loadLibrary加载进内存。在加载和寻找动态库时,Java会判断系统并扩展库名,在Windows平台下cms会被扩展成libcms.dll,Android作为基于linux的系统,则会依照linux被扩展成libcms.so,也就是我们常说的xxx SO库,解压APK取出libcms.so库,我们使用ida打开,默认加载,注意观察IDA左下角,地址值不变化时即加载完毕。 如何找到getUserInfo函数的实现代码?按照惯例,查看Exports栏——函数导出表

Hotspot 垃圾回收之CollectorPolicy (二) 源码解析

女生的网名这么多〃 提交于 2020-01-17 04:50:09
目录 一、GC_locker 1、lock_critical / unlock_critical 2、check_active_before_gc 3、stall_until_clear 二、TwoGenerationCollectorPolicy 三、ConcurrentMarkSweepPolicy 四、ASConcurrentMarkSweepPolicy 五、GenerationSpec 本篇继续上一篇 《Hotspot 垃圾回收之CollectorPolicy (一) 源码解析》 讲解CollectorPolicy的其他子类及其相关类的实现。 一、GC_locker GC_locker的定义在hotspot/src/share/vm/memory/gCLocker.hpp中,用来跟JNICritical_lock配合使用,实现当线程处于JNI关键区的时候不能执行GC的功能,该类定义的属性只有三个,如下: static volatile jint _jni_lock_count; //处于JNI关键区的线程个数 static volatile bool _needs_gc; //Java堆内存不足,需要GC static volatile bool _doing_gc; //是否在执行GC 重点关注以下方法的实现。 1、lock_critical / unlock