1 什么是JNI

JNI Java本地开发接口

JNI是一个协议,这个协议用来沟通java代码和外部的本地代码(C/C++)

通过这个协议,java代码就可以调用外部的C/C++代码,外部的C/C++代码也可以调用Java代码。

2 为什么用JNI

1  JNI扩展了java虚拟机的能力,驱动开发(wifi-hotspot)2.3无线热点共享

2  Native code效率高,数学运算,实时渲染的游戏上,音视频处理(极品飞车),opengl,ffmpeg

3  复用代码(文件压缩,人脸识别)

4  特殊的业务场景

3 怎么用JNI

1 C/C++语言

2 掌握java ini流程

3 NDK(native develop kits)

5 配置cygwin64的环境变量的方式是编写\Cygwin\etc\profile,将ndk的路径配置到path里面,截图如下:

打开Cygwin输入:Make –v,结果如下:

显示出来GNI Make的版本,说明我们的cygwin模拟的Linux编辑环境模拟成功。

输入ndk-build,出现以下结果:

显示出上面的效果,说明环境变量已经配置好了。

6 同样可以将这个变量配置到windows下的环境变量中:配置如下:

进入CMD命令行窗口中,如果出现以下结果,说明配置成功:

当配置了第6步之后,若cygwin没有配置成功时,也可以在window中的cmd命令行中使用ndk-build.

7 jni中的数据类型(后面是Java中的类型,左边是C语言中的类型):

#ifdef HAVE_INTTYPES_H

# include <inttypes.h>      /* C99 */

typedef uint8_t         jboolean;       /* unsigned 8 bits */

typedef int8_t          jbyte;          /* signed 8 bits */

typedef uint16_t        jchar;          /* unsigned 16 bits */

typedef int16_t         jshort;         /* signed 16 bits */

typedef int32_t         jint;           /* signed 32 bits */

typedef int64_t         jlong;          /* signed 64 bits */

typedef float           jfloat;         /* 32-bit IEEE 754 */

typedef double         jdouble;        /* 64-bit IEEE 754 */

#else

typedef unsigned char   jboolean;       /* unsigned 8 bits */

typedef signed char     jbyte;          /* signed 8 bits */

typedef unsigned short  jchar;          /* unsigned 16 bits */

typedef short          jshort;         /* signed 16 bits */

typedef int            jint;           /* signed 32 bits */

typedef long long      jlong;          /* signed 64 bits */

typedef float          jfloat;         /* 32-bit IEEE 754 */

typedef double        jdouble;        /* 64-bit IEEE 754 */

#endif

/* "cardinal indices and sizes" */

typedef jint            jsize;

8 案例效果(下面的土司是调用C语言代码显示的):

接下来编写案例,使用java代码调用C代码,创建项目helloworldformc,代码结构如下:

其中libs下的内容如下:

9 编写MainActivity,代码如下:

package com.example.helloworldformc;

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.widget.Toast;

public class MainActivity extends Activity {

// 1 定义一个c方法的接口   相当于在java代码中定义了一个接口

//接口的实现方法是C语言实现的

public native String helloWorldFromC();

// 变态命名
         public native String hello_world_from_c();

// 5 步在java代码中 引入库函数

static{

System.loadLibrary("hello");// 注意事项 去掉前面的lib 后面的.so

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

public void click(View view){

// 弹出一个土司 土司的内容 是c代码写出来

// 第6步

Toast.makeText(getApplicationContext(), helloWorldFromC(), 0).show();

}

}

10 在项目下创建一个jni目录(这个是必须的),开始编写Hello.c,代码如下:

#include <stdio.h>

#include <jni.h>

/*

* 对应的是:public native String helloWorldFromC(){}

* jstring:表示的是返回的是String类型的

* 函数名称规则是:Java_包名_类名_方法名。

*

* 注意:包名之间的"."在下面要变成下划线

*/

jstring Java_com_example_helloworldformc_MainActivity_helloWorldFromC(JNIEnv* env,jobject obj) {

//2步  实现C代码

//返回一个java String类型的字符串,使用一下函数

//jstring     (*NewStringUTF)(JNIEnv*, const char*);

//(*env) 相当于 JNINativeInterface* JNIEnv

//*(*env)  相当于 JNINativeInterface

//可以通过下面两种方式返回参数

//return (**env).NewStringUTF(env,"helloworldfromc");

return  (*env)->NewStringUTF(env,"helloworldfromc");

//android.mk 告诉编译器  如何把C代码打包成函数库

//3 生成.mk文件

//4 步  把C代码  打包成函数库

}

/*这里JNIEXPORT表示的是通过工具生成的,这时候也可以将JNIEXPORT去掉*/

JNIEXPORT jstring JNICALL Java_com_example_helloworldformc_MainActivity_hello_1world_1from_1c

(JNIEnv * env, jobject obj){

}

注意:上面的这个源文件的类名也可以通过javah命令生成,生成过程如下:

(1)       如果JDK使用的是1.6,使用javah命令前要到达:项目目录\bin\classes目录下

(2)       如果JDK使用的是1.7,使用javah命令前要达到:项目目录\bin\src目录下:

例如(我使用的是JDK1.7):

在项目中生成.h:

11 Android.mk文件的内容如下:

#一个Android.mk文件必须下面这个变量开头,它用于定位

#它用于定位你的源文件,my-dir这个宏是构件系统提供的,

#它用于返回当前目录的路径(这个目录包含Android.mk它自己)

LOCAL_PATH := $(call my-dir)

#CLEAR_VARS也是build system构件系统提供的,指定到一个指定的GNU Makefile文件

#这个Makefile文件帮你去清除一些LOCAL_XXX变量(比如:LOCAL_MODULE,LOCAL_SRC_FILES

#,LOCAL_STATIC_LIBRARIES.等等...),除了LOCAL_PATH.

include $(CLEAR_VARS)

#LOCAL_MODULE变量必须在你的Android.mk文件中定义。名称必须唯一

#并且不能包含一些空格,要注意的是构件系统会自动的添加适当的前缀和前缀

#换一句话说,一个命名为"foo"的共享库模块,会被生成"libfoo.so"文件。

#重要提示:如果你定义的模块名称是"libfoo",构建系统将不会添加"lib"前缀,

#并且也会生成"libfoo.so"文件。

LOCAL_MODULE    := hello

#LOCAL_SRC_FILES变量必须包含一个C或者C++的源文件集合,这些文件最终会被用于

#生成一个module,注意的是,这里不应该有头文件和包含文件,因为构件系统自动为您

#添加这些文件,只需要列出源文件就行了。

#注意:默认的C++源文件的后缀名是.cpp,同样你也可以通过LOCAL_CPP_EXTENSION来自定义

#CPP的后缀名(例如:".cxx"可以,"cxx"不可以)

LOCAL_SRC_FILES := Hello.c

include $(BUILD_SHARED_LIBRARY)

12 接下来使用cygwin,使用ndk-build来编译程序

(1)、如想将c变成.so的库,需要使用ndk-build命令

(2)、将路径路径切换到工程目录下。

(3)、然后执行ndk-build这个操作(这个操作直接指定到项目路径下就可以了)

注意:在使用这个ndk-build功能之前,需要有Android.mk文件(告诉编译器,如何将C代码打包成函数库。具体的Android.mk怎么使用可以看ndk中的Android.html文档)



01_JNI是什么,为什么使用,怎么用JNI,Cygwin环境变量配置,NDK案例(使用Java调用C代码),javah命令使用相关推荐

  1. JNI和NKD入门系列二,mac环境下配置NDk,并在android studio上进行JNI开发

    1.下载并配置NDK NDK各版本下载地址在此http://blog.csdn.net/shuzfan/article/details/52690554,对应好各自系统.(压缩文件记得解压) 接下来将 ...

  2. JNI实现Java调用C代码Demo AndroidStudio

    JNI(Java Native Interface)的本意是Java本地调用,它是为了方便java调用C/C++等本地代码所封装的一层接口 Android NDK(Native Development ...

  3. android java调用参数,如何从命令行调用Android JNI函数并传递Java对象参数

    一.前言 当我们对某个使用原生库(native library)的恶意软件或者应用进行分析或渗透测试时,如果能够对库函数进行隔离和执行是再好不过的事情,这样做我们就可以使用其自身的代码来调试对抗恶意软 ...

  4. android jni 结构体_Android应用开发Android JNI-c/c++调用java方法

    本文将带你了解Android应用开发Android JNI-c/c++调用java方法,希望本文对大家学Android有所帮助. " Android   JNI-c/c++调用java方法, ...

  5. JNI 最简单的Java调用C/C 代码

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! JNI_ ...

  6. eclipse调用JNI之环境的搭建

    因为项目中要在Java中调用C++编好的代码,即用eclipse调用动态链接库,故花了点时间研究在eclipse中使用JNI. 有时候因为Java本身特性的限制,单独使用Java语言可能不能完全满足应 ...

  7. 利用JNI技术在Android中调用C++代码

    JNI是Java Native Interface的简称,也就是Java本地接口,它提供了若干的API实现Java和其它语言的通信(主要是C&C++). 1.打开Eclipse,File--& ...

  8. Java调用库文件(JNI)(android对此有所改变)

    1.准备java 程序 testdll.java,内容为: public class testdll {  static {  System.loadLibrary("goodluck&qu ...

  9. JAVA用JNI方法调用C代码实现HelloWorld

    一.首先是java运行环境的搭建,到官网下载java jdk安装即可(注意要修改环境变量).还可以顺便安装eclipse. 二.编写java代码,文件名HelloWorld.java public c ...

最新文章

  1. 转 关于 D3D的 SetRenderState 以及AlphaBlend 和AlphaTest
  2. linux 内核参数somaxconn TCP监听队列长度
  3. python 开发版-Micropython开发板固件烧写教程
  4. HTTP状态码对照表(全部状态_建议收藏)
  5. 《MATLAB图像处理375例》——1.8 MATLAB程序流程控制结构
  6. ionic3 隐藏子页面tabs
  7. Oracle备份与恢复 关于expdp导出远程数据到本地的使用
  8. python该怎样使用_Python 应该怎么去练习和使用?
  9. Python3.6 所有内置函数
  10. Silverlight 2 跨域访问控件与WebService的资料整理
  11. php indexof(,JavaScript indexOf() 方法
  12. pr视频剪辑中工具栏功能详解
  13. 如何缩小png图片大小kb?如何让png图片变小?
  14. k8s--基础--12.2--pod--生命周期,状态,重启策略
  15. vue 实现抽奖大转盘
  16. Ubuntu下搭建R语言开发环境
  17. Django实战教程
  18. x3650m3服务器如何安装系统,IBM X3650 M3服务器安装windows 2003的方法
  19. SharePoint 2013 文档库“样式”变了
  20. 淘宝API item_search_img - 按图搜索淘宝商品(拍立淘)图片搜索

热门文章

  1. python读写、创建 文件(一)
  2. 电力论文:基于牛顿拉尔逊(直角坐标)的电气潮流计算(python实现)
  3. OpenCASCADE绘制测试线束:数据交换命令之XDE 命令概览
  4. wxWidgets:wxWidgets 中的 Unicode 支持
  5. boost::safe_numerics模块实现测试自定义异常的测试程序
  6. boost::search_n相关的测试程序
  7. boost::python模块实现使用原始指针访问数据的示例
  8. boost::gil::view_type_from_pixel用法的测试程序
  9. boost::geometry::detail::overlay::get_relative_order用法的测试程序
  10. VTK:可视化算法之TensorAxes