Android面试题:对JNI和NDK的理解

JNI和NDK是面试经常被问到的热点问题,在这里做一个记录。
1.阐述你对JNI的理解
 JNI的全称是Java Native Interface(Java本地接口)是一层接口,是用来沟通Java代码和C/C++代码的,是Java和C/C++之间的桥梁。通过JNI,Java可以完成对外部C/C++库函数的调用,相对的,外部C/C++也能调用Java中封装好的类和方法。
 Java的优点是跨平台,和操作系统之间的调用由JVM完成,但是一些和操作系统相关的操作就无法完成,JNI的出现刚好弥补了这个缺陷,也完善了Java语言,将java扩展得更为强大。
 
JNI的应用场景:
实际中的驱动都是C/C++开发的,通过JNI,Java可以调用C/c++实现的驱动,从而扩展Java虚拟机的能力。另外,在高效率的数学运算、游戏的实时渲染、音视频的编码和解码等方面,一般都是用C开发的。

2.NDK的理解
NDK(Native Development Kit)是Android所提供的一个工具集合,通过NDK可以在Android中更加方便地通过JNI来调用本地代码(C/C++)。NDK提供了交叉编译器,开发时只需要修改mk文件就能生成特定的CPU平台的动态库。

3.JNI开发的一般步骤
(1)创建一个Android工程,在Java代码中中声明一个native方法。
例如:

public class TestHelloActivity extends Activity{
   public native String sayHello();
   ....
}

(2)使用javah命令生成带有native方法的头文件。

javah com.xxx.TestHelloActivity

注意事项:
JDK1.7 需要在工程的src目录下执行上面的命令,JDK1.6 需要在工程的bin/classes目录下执行以上命令。
(3)在该Android工程中创建JNI目录,并在jni目录中创建一个Hello.c文件,根据头文件实现C代码。写C代码时,结构体JNIEnv*对象对个别object对象很重要,在实现的C代码的方法中必须传入这两个参数。具体代码如下:

jstring Java_com_xxx_TestHelloActivity_sayHello(JNIEnv* env,jobject obj){
	char* text = "hello from c!";
	return (**env).NewsStringUTF(env,text);
}

(4)在JNI的目录下创建一个Android.mk文件,并根据需要编写里面的内容,例如:

#LOCAL_PATH是所编译的C文件的根目录,右边的赋值代表根目录即为Android.mk所在的目录
LOCAL_PATH:=$(call my-dir)
#在使用NDK编译工具时对编译环境中所用到的全局变量清零
include $(CLEAR)VARS)
#最后声称库时的名字的一部分
LOCAL_MODULE:=hello
#要被编译的C文件的文件名
LOCAL_SRC_FILES:=Hello.c
#NDK编译时会生成一些共享库
include $(BUILD_SHARED_LIBRARY)

(5)在工程的根目录下执行ndk_build命令,编译.so文件
(6)在调用Native()方法前,加载.so的库文件,例如:

static  {
	System.loadLibrary("Hello");
}
//(文件名个Android.mk文件中的LOCAL_MODULE属性指定的值相同)

你可能感兴趣的:(Android基础)