Android本地接口JNI的使用

本地接口JNI的使用总结

1、简介

JNI是Java Native Interface的简写,即为Java语言的本地接口,它允许我们在Java代码中去使用其他语言的功能,比如:C、C++及汇编语言等。

一般,在Android当中,我们会把某些敏感或是核心的功能放在C/C++中实现,因为Java或Android的安全性不是很好,容易被反编译或是破解,而用C/C++实现的话,安全性好,并且C/C++是运行在底层的,好处可想而知。

2、使用

对于JNI的使用比较简单,分为以下几步:

A、新建一个Android项目

B、创建本地接口

C、创建对应本地接口的头文件和源文件

D、使用工具ndk-build编译生成.so库文件

E、将生成的.so文件放入到项目的libs/armeabi使用

下面就按照上面的步骤一步步进行,以在屏幕上显示HelloJni来演示JNI的使用流程:

A、新建项目

我的项目目录如下:

 Android本地接口JNI的使用

 

B、新建本地的接口文件(JNIService)

内容如下:

/*

 * JNI的本地方法

 */

public class JNIService {

static {

System.loadLibrary("hello_jni");

}

public static native String getString();// 获取字符串

}

C、创建本地接口对应的C/C++文件

头文件:

我们可以使用jdk的命令工具javah来生成需要的头文件,当然,也可以自行编写头文件(这需要你对C比较熟悉)。

具体如下:

首先,运行新建接口的项目,此时会在项目的bin目录下生成对应的.class文件,我们只需要对定义了本地接口的类进行编译生成头文件即可,具体如下:

切换到项目的目录下,执行命令:javah -classpath bin/classes -d jni com.demo.hellojni.JNIService,这里我们新建了一个目录jni来存放生成的头文件,我的目录如下所示:

 Android本地接口JNI的使用

接下来,就是编写源文件了,这里我们使用Visual studio 来编写C文件,上面的头文件内容如下:

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

#include <jni.h>

/* Header for class com_demo_hellojni_JNIService */

 

#ifndef _Included_com_demo_hellojni_JNIService

#define _Included_com_demo_hellojni_JNIService

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     com_demo_hellojni_JNIService

 * Method:    getString

 * Signature: ()Ljava/lang/String;

 */

JNIEXPORT jstring JNICALL Java_com_demo_hellojni_JNIService_getString

  (JNIEnv *, jclass);

 

#ifdef __cplusplus

}

#endif

#endif

下面我们编写对应的源文件JNIService.c,这个文件的编写需要参照头文件的规范,具体如下:

#include <jni.h>

 

JNIEXPORT jstring JNICALL Java_com_demo_hellojni_JNIService_getString(JNIEnv * env, jobject obj)

{

return (*env)->NewStringUTF(env,"HELLO NDK!");

}

 

好了,头文件和源文件都编写完成,接下来我们需要再编写一个Android.mk文件来,内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := hello_jni

LOCAL_SRC_FILES := JNIService.c

include $(BUILD_SHARED_LIBRARY)

接下来,我们将上面的头文件、源文件及Android.mk文件放到JNI。

D、编译生成的文件

这里使用了ndk来编译资源文件,所以需要先安装和配置NDK,另外我们需要第三方软件(这里我使用Cygwin协助编译),具体可参考博客:

http://blog.csdn.net/jiangwei0910410003/article/details/17710243

 

打开Cygin软件,定位到上面的jni目录,我的目录:

 Android本地接口JNI的使用

执行命令:$NDK/ndk_build进行编译,执行结果如下:

 Android本地接口JNI的使用

编译成功后,会生成两个文件目录,分别为libs和obj,这里我们只需要关注libs即可。具体如下:

 Android本地接口JNI的使用

到这里,我们需要已久的.so文件就可以使用了,将这个.so文件放到项目目录的libs/armeabi(如果没有 则新建这个目录,只有在这个目录下的so文件才会被加载)。

最后,就是怎样调用这个JNI了,具体如下:

public class HelloJNIActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_hello_jni);

}

public void helloJNIShow(View v) {

String helloJNI = JNIService.getString();

Toast.makeText(this, helloJNI, Toast.LENGTH_SHORT).show();

}

}

这样就可以运行我们的项目,当我们点击欢迎语的时候,就是显示C/C++返回的信息提示了,效果图如下:

 

 Android本地接口JNI的使用

 

在后面的文章中,我会继续列举一个有实际意义的例子,比如:Android当中的加密和解密实现

 

/*

* Android技术交流群号:179914858

*  欢迎加入

*/

 

Android本地接口JNI的使用

上一篇:基础教程5——Start Developing iOS Apps Today——从今天开始开发IOS(IOS7版)系列源文档翻译(六)


下一篇:Flash AS制作祖国万岁烟花动画文字特效