NDK09_JNI编译过程及AS新建一个JNI项目

NDK开发汇总

一 JNI原理

1 编译

cpu识别的是“0101”的字符

c/c++ ========= 二进制文件

  • 编译:xxx.c ------> windows .obj 语法 Linux .o

  • 链接:.o -----> log.so

2 编译规则:

  • Eclipse GUN ----> Android.mk
  • Android Studio: LLVM ----> CMakeList.txt

三段式
cppFlags “-frtti -fexceptions”

3 Jni原理

在这里插入图片描述

二 AS新建一个支持JNI的项目

1 新建项目

new Project 勾选下面两项即可,在CMakeList.txt中配置对应的c文件声明
在这里插入图片描述
在这里插入图片描述
CMakeList.txt 用来进行JNI引用的配置

add_library 指定需要编译那些文件
target_link_libraries 指定了需要链接那些so库
JNI项目一定包含指定编译文件和需要链接哪些so库这两个动作

注意: 新建项目报错:External Native Build Issues
解决方法:提升.build:gradle版本

dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
    }

提升至:

dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
    }

2 初始化

  • 将cpp路径下的native-lib.cpp删除,清理MainActivity的jni调用,并新建一个native-lib.c文件,
  • 切换到Project视图,在src/main/cpp下面可以找到native-lib.c
  • 在CMakeList.txt中修改配置:add_library 中原先配置的native-lib.cpp修改为新建的ative-lib.c文件路径:src/main/cpp/native-lib.c

3 声明一个native 方法,生成.h头文件

  • 创建一个java类,其中声明一个native方法
public class FileUtils {

    public static native void diff(String  path,String pattern_Path,int file_number );
}

  • 可以直接快捷键生产头文件,或者javah直接生成
  • 如果javah失败,可以:
    先生成class文件
C:\rj\workspace\NDK\app\src\main\java\com\ray\ndk\ndk>javac FileUtils.java

然后javah,注意两条命令的路径

C:\rj\workspace\NDK\app\src\main\java>javah -classpath . -jni com.ray.ndk.ndk.FileUtils

最好在\java路径下生成一个com_ray_ndk_ndk_FileUtils.h文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_ray_ndk_ndk_FileUtils */

#ifndef _Included_com_ray_ndk_ndk_FileUtils
#define _Included_com_ray_ndk_ndk_FileUtils
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_ray_ndk_ndk_FileUtils
 * Method:    diff
 * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_com_ray_ndk_ndk_FileUtils_diff
  (JNIEnv *, jclass, jstring, jstring, jint);

#ifdef __cplusplus
}
#endif
#endif

4 实现.h定义的方法

  • 将要实现的方法拷贝到native-lib.c中,c中引入com_ray_ndk_ndk_FileUtils.h
  • 引入#include <android/log.h>打印日志
  • 定义
    #define TAG “RAY”
    #define LOGI(…) __android_log_print(ANDROID_LOG_INFO, TAG, VA_ARGS)
  • 实现
#include "com_ray_ndk_ndk_FileUtils.h"
#include <android/log.h>
#define TAG "RAY"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)

JNIEXPORT void JNICALL Java_com_ray_ndk_ndk_FileUtils_diff
  (JNIEnv * env, jclass clazz, jstring path, jstring pattern_Path, jint file_num){
  LOGI("JNI的方法被调用");
}

5 使用

  • 加载库
public class FileUtils {

    static {
        System.loadLibrary("native-lib");
    }

    public static native void diff(String  path,String pattern_Path,int file_number );
}
  • 调用
public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        diff();
    }

    public void diff(){
        Log.d("RAY", "diff");
        FileUtils.diff("ss","33" ,4 );
    }
}
  • 运行后打印:
    03-21 10:39:20.212 24471-24471/com.ray.ndk.ndk D/Ray: diff
    03-21 10:39:20.213 24471-24471/com.ray.ndk.ndk I/RAY: JNI的方法被调用

6 Demo

代码

发布了269 篇原创文章 · 获赞 123 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/baopengjian/article/details/104957181