引
本次广州出差,有机会接触到NDK开发,当然还只是习得皮毛。个人认为C/C++实现优点有三:
- 脱离JVM,运行效率高。
- 安全性强,核心代码不易破解。
- 代码可移植性强,此次核心代码就共用于IOS和Android。
实现
1.写native方法。
public class NdkEngine { public static native int nativeCalc(int n); }
2.命令行中通过javah生成对应头文件。
D:\workspace\20150310\demo\app>javah -classpath D:\workspace\20150310\demo\app\build\intermediates\classes\debug -d jni com.felix.opticalixdemo.demo.ndk.NdkEngine
3.粘合层c代码实现。
com_felix_opticalixdemo_demo_ndk_NdkEngine.c
#include "com_felix_opticalixdemo_demo_ndk_NdkEngine.h"
#include "calc.h"
JNIEXPORT jint JNICALL Java_com_felix_opticalixdemo_demo_ndk_NdkEngine_nativeCalc(JNIEnv *env, jclass clazz, jint n){
return calc(n);
}
4.本地.h和.c代码实现(calc.h calc.c)。
#ifndef _CALC_H_ #define _CALC_H_ #include <stdint.h> extern uint64_t calc(unsigned int n); #endif #include "calc.h" uint64_t calc(unsigned int n){ return n;//do some calc }
5.编写makeFile。
Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := ndk_calc_demo LOCAL_SRC_FILES := com_felix_opticalixdemo_demo_ndk_NdkEngine.c calc.c //add all your .c files include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_ABI := armeabi-v7a
6.gradle中添加ndk编译任务。
注意先配置ndk环境。下载最新ndk,配置环境变量。并在local.properties中配置ndk路径。
ndk.dir=D\:\\android-ndk-r10e
在使用native方法的module下,build.gradle中添加ndk任务。记得同时指定jniLibs目录。
sourceSets { main { jniLibs.srcDir 'libs/'//.so files generate here jni.srcDirs = [] //disable automatic ndk-build call } } task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') { def ndkDir = project.plugins.findPlugin('com.android.application').sdkHandler.getNdkFolder(); def baseDir = projectDir.absolutePath; def ext = projectDir.absolutePath; if (Os.isFamily(Os.FAMILY_WINDOWS)) { ext = ".cmd"; } else { ext = ""; } commandLine "$ndkDir/ndk-build" + ext, '-C', baseDir + '/jni', '-j4', 'NDK_DEBUG=1' } tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn ndkBuild }
7.make Project。会自动将so文件导出到libs文件夹中。
- 8.static代码块System.loadLibrary(“module_name”)。
- 9.调试ndk (待验证)
使用ndk-stack调试ndk(或者利用gdb? http://blog.csdn.net/xqhrs232/article/details/7532276)- 运行终端,进入jni所在目录,输入adb logcat | ndk-stack -sym .(最后的.代表当前目录)
- 这时再运行程序,如果native方法crash就会打印出c代码崩溃的位置。