JAVA和Android的JNI的使用

JNIJava Native Interface的缩写.

设计目的是:标准JAVA库不支持一些平台特性,你可以用别的语言,编写代码使得你的软件支持这些平台特性,也可能你的程序需要用低级语言编写一些算法以提高程序的效率.这些情况都可能是你使用JNI的原因.

JNI的编写步骤:

1.编写带有native 声明的java.

2.编译java文件成class

3.使用javah -jni com.ikags.project.XXXX 编译成.h文件

4.使用C/C++编写代码

5..h.c(.cpp)文件编译成.dll(.so)文件(根据平台不同,用不同的工具,PC平台VS2005就可以,android平台的话,cygwin+android NDK(android  Native Development Kit)进行开发.

6..dll(.so)文件提供给你的项目,system.loadLibrary方法调用.

下面2个平台一起讲解.不同的部分用蓝色加以区分.

1.编写一个带有native声明的java.其中native方法就是需要生成的可调用的方法.这一步很简单
====代码====

package com.ikags;

public class AJni {

  public native void display();

  public native int plus(int x,int y);

  public native int reduce(int x,int y);

}

====代码====

2.编译成class文件

可以通过命令行中的 javac AJni.java进行编译.最简单的方法,J2SE项目直接右键run然后,可以在项目下的bin目录中找到AJni.class文件.目的达成.如果通过命令行编译会出现问题,请找到JAVA 文件夹下面对应JDKbin目录,把文件copy到里面执行(或者在环境变量中配置bin目录的位置)

3.使用javah -jni com.ikags.project.XXXX 编译成.h文件

通过命令行中的javah -jni com.ikags.project.XXXX 编译成.h文件,其中在编译.h文件的时候切记加入路径,这个有时候会引起一些奇怪的问题,比如说调用失败,调用不到啥的,原因未知.

如果编译失败的话,处理方法同编译成class文件,请找到JAVA 文件夹下面对应JDKbin目录,把文件copy到里面执行(或者在环境变量中配置bin目录的位置)
此时生成文件com_ikags_AJni.h

4.使用C/C++编写代码

其中前一阶段生成的.h头文件如下:
====代码====

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class com_ikags_AJni */

#ifndef _Included_com_ikags_AJni

#define _Included_com_ikags_AJni

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     com_ikags_AJni

 * Method:    display

 * Signature: ()V

 */

JNIEXPORT void JNICALL Java_com_ikags_AJni_display

  (JNIEnv *, jobject);

/*

 * Class:     com_ikags_AJni

 * Method:    plus

 * Signature: (II)I

 */

JNIEXPORT jint JNICALL Java_com_ikags_AJni_plus

  (JNIEnv *, jobject, jint, jint);

/*

 * Class:     com_ikags_AJni

 * Method:    reduce

 * Signature: (II)I

 */

JNIEXPORT jint JNICALL Java_com_ikags_AJni_reduce

  (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus

}

#endif

#endif

====代码====

这里是不需要进行任何更改的.这里只要自己再写一个.c(.cpp)文件,其中包含有这三个方法即可,这里特别注意,PCandroid平台支持的库不一样,如果调用了不支持的库的话,后面的编译会出错,这个需要特别注意一下.
PC端的话还好说,android平台方面,目前1.6NDK只支持Math,C标准库,ZLib,Log库和OpenGL ES.(这里举例来说PC端的JNI支持printf,但是如果android上不支持,这时候针对android平台开发的话,编译时候就会出错)

我编写的com_ikags_AJni.c如下:
====代码====

#include <com_ikags_AJni.h>

JNIEXPORT void JNICALL Java_com_ikags_AJni_display

  (JNIEnv *, jobject){

  return;

  };

JNIEXPORT jint JNICALL Java_com_ikags_AJni_plus

  (JNIEnv *, jobject, jint x, jint y){

    return x+y;

    };

JNIEXPORT jint JNICALL Java_com_ikags_AJni_reduce

  (JNIEnv *, jobject, jint x, jint y){

    return x-y;

};
====代码====


5.h.c(.cpp)文件编译成.dll(.so)文件(根据平台不同,用不同的工具,PC平台VS2005就可以,android平台的话,cygwin+android NDK(android  Native Development Kit)进行开发.

这里的编译就体现了不同平台的区别

PC:

直接通过VS2005就可以编译.编译时候如果出现找不到某些.h文件的错误的话(fatal error C1083: 无法打开包括文件L ..........  No such file or directory),参考下面更改:
项目--->属性---->配置属性---->C/C++---->常规---->附加包含目录”选项中有很多include下的库 ,JAVA JDK里面incude的和里面的win32这两个路径添加入目录中,再尝试编译.一般来说代码正确的话,可以编译通过.这里生成myjni.dll.

Android:`
这里要通过cygwin android NDK进行编译,cygwin安装步骤这里不再多说,android NDK下载后直接解压就OK.cygwin记得安装几个C的编译器.

打开cygwin,看到命令行模式通过 cd 命令进入NDK的目录,然后运行

build/host-setup.sh .可以看到一些信息,如果没有报错的话,就正常安装完毕.

编译本身命令很简单, make APP=hello-jni -B 就可以尝试编译 自带实例.编译成功的话,说明配置成功,然后我们开始编译我们自己的程序.

NDK目录的apps文件夹下,建立一个myjni文件夹,hello项目里面复制Application.mkmyjni文件夹里面,用文本编辑器编辑文本为
APP_PROJECT_PATH := $(call my-dir)

APP_MODULES      := myjni

然后建立一个jni文件夹,hello项目里面复制一个Android.mkjni文件夹目录,然后用文本编辑器更改里面的相关参数.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := myjni

LOCAL_SRC_FILES := com_ikags_AJni.cpp

include $(BUILD_SHARED_LIBRARY)

这时候把你的.h.c(.cpp)等文件复制到这个目录下.

然后用cygwin 运行make APP=myjni -B

如果编码没有错误的话,会自动生成

\libs\armeabi\libmyjni.so文件,至此androidJNI文件生成完成.

6..dll(.so)文件提供给你的项目,system.loadLibrary方法调用.

PC:

dll文件复制入程序跟目录,保留第一步写的native Java代码.在需要用的代码里面加入:

 static

  {

    System.loadLibrary("myjni");

  }

在运行方法里面加入:

    AJni newlib = new AJni();

int i = newlib.plus(330, 1003);

输出i即可测试是否有效.

Android:

libs整个目录复制到android项目下.这里要注意的是loadLibrary读取的名字和lib的名字不同.这里我们的so文件为libmyjni.so,但是我们下面写的loadLibrarymyjni,这点是要注意下的
在自己的Activity里面添加代码:

 static

  {

    System.loadLibrary("myjni");

  }

在运行方法里面加入:

    AJni newlib = new AJni();

int i = newlib.plus(330, 1003);

这是可以用Log.v方法来查看i的数值.

针对android真机测试,需要将.so文件push入手机,system中的lib目录.需要可以自行google别的相关安装文章.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值