NDK开发在AS上实现的简易流程

本次广州出差,有机会接触到NDK开发,当然还只是习得皮毛。个人认为C/C++实现优点有三:

  1. 脱离JVM,运行效率高。
  2. 安全性强,核心代码不易破解。
  3. 代码可移植性强,此次核心代码就共用于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
    1. 运行终端,进入jni所在目录,输入adb logcat | ndk-stack -sym .(最后的.代表当前目录)
    2. 这时再运行程序,如果native方法crash就会打印出c代码崩溃的位置。