zoukankan      html  css  js  c++  java
  • 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开发环境搭建

  • 相关阅读:
    解决:Could not resolve archetype org.apache.maven.archetypes
    Spring MVC配置MyBatis输出SQL
    Spring集成MyBatis 通用Mapper以及 pagehelper分页插件
    关于SpringMVC或Struts2接受参数接收不到的原因
    配置quartz启动时就执行一次
    ajaxFileUpload进行文件上传时,总是进入error
    spring mvc注入配置文件里的属性
    java中将一个文件夹下所有的文件压缩成一个文件
    flume failed to start agent because dependencies were not found in classpath
    ubuntu不能安装pip unable to install pip in unbuntu
  • 原文地址:https://www.cnblogs.com/android-blogs/p/5816898.html
Copyright © 2011-2022 走看看