转载

Jni/Ndk 开发学习记录(一)

治疗拖延症的唯一办法就是:一想起些什么 / 要做些什么就 TM 立马去做!

是的,突然想起我不会 JNI、NDK 开发。解决办法:立马去学!

一:配置 NDK 环境

  • 下载 NDK
  • 写入到配置文件

二:理解分层

三部分:

  • Java 上层
  • JNI 桥梁
  • 底层(C or C++)

三:代码开发(以一个计算器为 DEMO)

Java 上层定义好 native 方法:

public class CalculatorHelper {      static {         System.loadLibrary("calculator");     }      public native static int add(int a, int b);     public native static int sub(int a, int b); }

新建 Calculator.hpp 文件,提供算法的底层,使用 C++ 实现:

#ifndef JNITEST_CALCULATOR_HPP #define JNITEST_CALCULATOR_HPP  class Calculator {     int add(int a, int b);      int sub(int a, int b); };  #endif //JNITEST_CALCULATOR_HPP

新建 Calculator.cpp 文件,具体算法实现 :

#include "Calculator.hpp"  int add(int a, int b){     return a + b; }  int sub(int a, int b){     return a - b; }

上层和底层都已经准备好了,只欠一个桥梁 JNI

JNI 实现过程:

编译 CalculatorHelper.java 生成 .class 文件,-d 指生成的目录

javac src/main/java/com/baitu/jnitest/CalculatorHelper.java -d src-gen/

根据 CalculatorHelper.class 生成 .h 文件:

javah -classpath src-gen/ -d jni/ com.baitu.jnitest.CalculatorHelper

生成的 .h 文件:

/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_baitu_jnitest_CalculatorHelper */  #ifndef _Included_com_baitu_jnitest_CalculatorHelper #define _Included_com_baitu_jnitest_CalculatorHelper #ifdef __cplusplus extern "C" { #endif /*  * Class:     com_baitu_jnitest_CalculatorHelper  * Method:    add  * Signature: (II)I  */ JNIEXPORT jint JNICALL Java_com_baitu_jnitest_CalculatorHelper_add   (JNIEnv *, jobject, jint, jint);  /*  * Class:     com_baitu_jnitest_CalculatorHelper  * Method:    sub  * Signature: (II)I  */ JNIEXPORT jint JNICALL Java_com_baitu_jnitest_CalculatorHelper_sub   (JNIEnv *, jobject, jint, jint);  #ifdef __cplusplus } #endif #endif

新建 CalculatorUtils.hpp ,把刚 .h 文件的代码拷贝过去,新建 CalculatorUtils.cpp ,JNI 具体实现:

#include "CalculatorUtils.hpp" #include "Calculator.cpp"  JNIEXPORT jint JNICALL Java_com_baitu_jnitest_CalculatorHelper_add   (JNIEnv *env, jobject thiz, jint a, jint b){         return add(a, b);   }  JNIEXPORT jint JNICALL Java_com_baitu_jnitest_CalculatorHelper_sub   (JNIEnv *env, jobject thiz, jint a, jint b){         return sub(a, b);   }

#include "Calculator.cpp" 引用底层,然后调用其相关算法方法: add(a, b)sub(a, b) ,完成 JNI 与 底层 交互。

到这里,JNI 已经编写完成。

配置两个 NDK 编译时的配置文件:

Android.mk

LOCAL_PATH := $(call my-dir)  include $(CLEAR_VARS)  LOCAL_MODULE := calculator LOCAL_SRC_FILES := CalculatorUtils.cpp  LOCAL_LDLIBS    := -lm -llog  include $(BUILD_SHARED_LIBRARY)

Application.mk :

APP_ABI := all

在 jni(存放 JNI 文件的文件夹必须命名为 JNI)的父目录运行命令:

ndk-build

然后会看到在同级目录下会创建一个 libs 文件夹,里面生成一堆 so 库,把它们拷贝到项目的 so 库目录下即可。

最后在 Java 调用 native 方法:

int a = 5; int b = 3; CalculatorHelper.add(a, b); CalculatorHelper.sub(a, b);

欧耶!完成 Java - JNI - C++ 调用!

原文  http://hackeris.me/2016/07/02/jni_mark_1/
正文到此结束
Loading...