Android NDK 入门实践

创建 Java 类

package com.baidu.hi.utils;

public class BVUtils {

    static {
        System.loadLibrary("BVUtils");
    }

    public static native String sayHello(String msg);
}

自动生成.h文件

  1. 从Android Studio的Terminal里进入到, /src/main/java 目录下, 一定要到这个文件夹下来执行命令操作。
  2. 执行javah com.baidu.hi.utils.BVUtils 即可, com.baidu.hi.utils.BVUtils是要生成.h文件的完整路径名,包名+文件名
  3. 然后就会在java目录下生成相应的.h文件com_baidu_hi_utils_BVUtils.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_baidu_hi_utils_BVUtils */

#ifndef _Included_com_baidu_hi_utils_BVUtils
#define _Included_com_baidu_hi_utils_BVUtils
#ifdef __cplusplus
extern "C" {  
#endif
/*
 * Class:     com_baidu_hi_utils_BVUtils
 * Method:    sayHello
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_baidu_hi_utils_BVUtils_sayHello  
  (JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

4.拷贝 .h 文件到jni 目录下, 别忘了配置 sourceSets

sourceSets {  
    main { jni.srcDirs = ['src/main/jni'] } 
}

还有下面这句话配置到 android {} 中,不然会提示引用找不到

externalNativeBuild {  
        ndkBuild {
            path 'src/main/jni/Android.mk'
        }
    }

实现

同目录下创建Hello.c, 并实现h里面的方法

#include "com_baidu_hi_utils_BVUtils.h"
#include <stdio.h>

JNIEXPORT jstring JNICALL Java_com_baidu_hi_utils_BVUtils_sayHello  
  (JNIEnv *env, jclass jclass, jstring string) {
    return (*env)->NewStringUTF(env, "Hello Jni");
}

创建 Application.mk 文件

APP_MODULES := BVUtils  
APP_ABI :=all  

创建 Android.mk文件

LOCAL_PATH := $(call my-dir)  
include $(CLEAR_VARS)  
LOCAL_MODULE :=BVUtils  
LOCAL_SRC_FILES =: Hello.c  
include $(BUILD_SHARED_LIBRARY)  

配置 gradle.build

defaultConfig {  
    ndk {
       moduleName 'BVUtils'
    }
}

gradle.properties 添加NDK 支持

android.useDeprecatedNdk = true  

打包 so 文件

切换到jni 目录下执行 ndk-build, 生成的 so 文件在当前目录下libs文件夹下。 如果运行打包生产的ndk在
~/build/intermediates/ndk/debug/lib/armeabi/libBVUtils.so 目录下,拷贝到~/libs/armeabi 下,java 加载 so 文件

static {  
        System.loadLibrary("BVUtils");
    }

需要注意了: loadLibrary 的名字并不是 so 文件的名字,而是之前 gradle 配置的moduleName

异常情况处理

  • Error: Your project contains C++ files but it is not using a supported native build system [closed]
将 gradle 中 sourceSets { } 块 放到 buildTypes {} 前面