使“java+c”的开发方式成为了官方支持的开发方式,NDK的本质就是为了让Android应用程序能方便的使用JNI技术而提供的一套工具集合,使用NDK主要是4大好处,第一个,代码的保护,,由于apk的java层代码很容易被反编译,而c/c++反汇编难度较大;第二个,可以很方便的使用开源库,因为很多的现存的开源库都是c/c++代码编写的;第三个,提高程序的执行效率,第四个,便于移植,使用c/c++写的库可以方便在其它的嵌入式平台上使用.这里还有一个问题就是如果在模拟器上运行的话,我们只能在ARM上运行,并不能在intel上运行,否则会无法加载那个so库文件
NDK环境搭建
第一步:下载NDK
第二步:创建一个Android工程
第三步:在该工程目录的根目录下创建一个jni目录,用来作为ndk的编译路径(NDK的脚本会根据jni目录中的c/c++文件以及mk文件进行编译生成so文件)
第四步:创建builder(builder会使用ndk中的工具将jni目录中的文件编译成为so文件)Project->Properties->Builders->New->Program
。
对了,这段代码实现的功能就是进行两个int的加减,
这里我们首先需要建立一个java文件
package com.jk.ndkdemo; public class NDKBridge { public native int add(int a,int b); }
然后我们通过jdk中javah工具,根据NDKBridge类生成.h,在使用命令行时,我们要先进入到bin\clsses javah com.jk.ndkdemo.NDKBridge,生成的.h的命名的规则是包名_类名.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_jk_ndkdemo_NDKBridge */ #ifndef _Included_com_jk_ndkdemo_NDKBridge #define _Included_com_jk_ndkdemo_NDKBridge #ifdef __cplusplus extern "C" { #endif /* * Class: com_jk_ndkdemo_NDKBridge * Method: add * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_jk_ndkdemo_NDKBridge_add (JNIEnv *, jobject, jint, jint); #ifdef __cplusplus } #endif #endif
接下来我们根据h文件中的内容,在jni目录中创建c文件
#include "com_jk_ndkdemo_NDKBridge.h" #include <stdlib.h> #include <stdio.h> #ifdef __cplusplus extern "C" { #endif JNIEXPORT jint JNICALL Java_com_jk_ndkdemo_NDKBridge_add (JNIEnv *env, jobject obj, jint a, jint b) { //将jni类型转换成C类型 int a1 = a; int b1 = b; int c1 = a1 + b1; //将C类型转成JNI类型 jint c = c1; return c; } #ifdef __cplusplus } #endif
然后我们创建mk文件
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := MyNDKDemo LOCAL_SRC_FILES := com_jk_ndkdemo_NDKBridge.c include $(BUILD_SHARED_LIBRARY)
这里的LOCAL_MODULE就是我们生成的so文件的名字,LOCAL_SRC_FILES就是我们根据这个文件来创建的,一旦我们保存,那么就会自动生成so文件
然后我们就需要先加载so文件,然后就可以使用了,这个步骤在activity中实现
package com.jk.ndkdemo; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.Toast; public class MainActivity extends Activity { // 加载so文件 static { System.loadLibrary("MyNDKDemo"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获得含有jni方法的对象 NDKBridge bridge = new NDKBridge(); // 调用jni方法 int t = bridge.add(3, 5); Toast.makeText(this, "" + t, Toast.LENGTH_SHORT).show(); } }
好了,一个简单的jni编程就完成了。