Android系统JNI编程总结

来源:互联网 发布:什么是淘宝seo 编辑:程序博客网 时间:2024/06/06 12:42

Android系统JNI编程总结

JNIJava Native Interface的简称,译为Java本地接口,是为JavaC/C++之间提供交互,使Java能调用C/C++代码,C/C++也能调用Java代码。在C/C++中能访问Java中的所有成员,不管是公共的还是私有的,因此就破坏了Java的安全性。

下面就来看一个基于AndroidJNI编程的简单例子

首先建立一个Android工程,如何建立Android工程就不多说。接下来在该工程中新建一个类(JNITest.java),在这个类中声明了一个本地(native)方法,该方法返回一个整数,如下:

package net.yxarm.JNITest;

public class JNITest {

static{

System.loadLibrary("JNITest");

}

public native int ReturnInt();

}

第二步:使用javah命令生成该本地方法的头文件,在Dos下进入该工程的src目录下,输入命令

javac net/yxarm/JNITest/JNITest.java

命令执行完成之后继续执行下面的命令

javah net.yxarm.JNITest.JNITest

net.yxarm.JNITest为该类的完整包名,执行完javah命令后,会在src目录下生成一个.h文件,在这里生成文件名为net_yxarm_JNITest_JNITest.h命名的规则是完整包名加类名。.h文件中的内容如下

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

#include <jni.h>

/* Header for class net_yxarm_JNITest_JNITest */

#ifndef _Included_net_yxarm_JNITest_JNITest

#define _Included_net_yxarm_JNITest_JNITest

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     net_yxarm_JNITest_JNITest

 * Method:    ReturnInt

 * Signature: ()I

 */

JNIEXPORT jint JNICALL Java_net_yxarm_JNITest_JNITest_ReturnInt

  (JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

JNIEXPORT jint JNICALL Java_net_yxarm_JNITest_JNITest_ReturnInt

  (JNIEnv *, jobject);

这句代码就是我们在Java中声明的本地方法ReturnInt,在JNI中的声明。并且会自动加上两个参数。

第三步:Java本地方法在JNI中的声明也有了,那么接下来就可以实现这个声明的方法,在Android工程的根目录下新建一个文件夹jni,在该文件夹下新建一个JNITest.cpp文件,在这个C++文件中实现我们的本地方法,并将生成的头文件拷贝到该文件夹下。在JNITest.cpp中实现很简单,只是返回一个整数。

#include <jni.h>

#include "net_yxarm_HelloTest_HelloTest.h"

JNIEXPORT jint JNICALL Java_net_yxarm_JNITest_JNITest_ReturnInt

  (JNIEnv *env , jobject obj)

  {

return 10;

  }

第四步:本地方法也实现了,那么接下来就是很重要的一步,将cpp文件打包成动态库文件(XXX.so),在打包之前还需要做一件事,就是写一个Android.mk的编译文件,下面就是编译该文件的Android.mk文件(注意:该名字不能更改

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := JNITest             //编译成动态库文件后的名字,libJNITest.so沿用的Linux的命名规则,会在前面自动加上lib

LOCAL_SRC_FILES := JNITest.cpp    //编译的源文件

       

include $(BUILD_SHARED_LIBRARY)   //将该源文件编译成动态库文件呢

如何将.cpp文件编译成动态库文件呢?Google提供了一个工具叫NDK(Native Development Kit,NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将sojava应用一起打包成apk。这些工具对开发者的帮助是巨大的),该工具的详细介绍请参考其它文章。

进入到该工程目录下,使用ndk-build命令(前提是在环境变量中配置好了NDK的目录),执行完之后,就会在该工程下产生一libs/armeabi/libJNITest.so

注意:不熟悉Linux操作系统的可以在Windows下使用cygwin工具编译,编译的过程是一样的,进入到该工程目录下,使用$NDK/ndk-build命令,$NDK就是在cygwin工具中配置的环境变量。

第五步:编译好动态库文件后,使用System.loadLibrary("JNITest")就能将该库加载到应用程序中,请参考JNITest.java文件。

注意:System.loadLibrary("JNITest")中不能写"libJNITest.so",要去掉前缀和后缀。

在应用程序中调用本地方法,查看方法的返回值是否是10 ,如果是那么恭喜你,已经学会了AndroidJNI编程的整个过程。

原创粉丝点击