• Android学Jni/Ndk 开发记录(一)


     

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

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


    一:配置 NDK 环境

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

    二:理解分层

    三部分:

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

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

    Java 上层定义好native方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    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++ 实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    #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文件,具体算法实现 :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    #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 指生成的目录

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

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

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

    生成的.h文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
    /* 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 具体实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    #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 :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    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:

    1
    
    APP_ABI := all
    

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

    1
    
    ndk-build
    

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

    最后在 Java 调用 native 方法:

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

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

    推荐:

    Android NDK开发环境搭建

  • 相关阅读:
    2-Add Two Numbers
    1-Two Sum
    解决spark-shell输出日志过多的问题
    安装配置Hive
    src与bin版本的区别
    AES加密时抛出java.security.InvalidKeyException: Illegal key size or default parameters
    hosts文件修改问题
    Spark垃圾邮件分类(scala+java)
    Spark常用机器学习算法(scala+java)
    Spark自带Pi程序运行
  • 原文地址:https://www.cnblogs.com/android-blogs/p/5816898.html
Copyright © 2020-2023  润新知