Android Studio 添加jni代码

昨天要写个apk 练习用opengl es 画图, 不想在java里边直接调opengles, 想通过jni在cpp里边去调, 所以需要加上jni代码, 弄了3小时才搞出来,感觉坑还有点多, 遂记录一下步骤方便后面使用, 添加jni的方法有多种,这里只记录下本人搞出来的那种.

1. 编写声明native 接口的java文件

声明3个native 接口

   public  native  void initImpl();
    public  native  void resizeImpl();
    public  native  void doDrawImpl();

Draw.java

//Draw.java

package com.example.test1;

public class Draw {

    public void init(){
        initImpl();
    }

    public void resize() {
        resizeImpl();
    }

    public void doDraw() {
        doDrawImpl();
    }

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



    public  native  void initImpl();
    public  native  void resizeImpl();
    public  native  void doDrawImpl();

}

其中, 上边 System.loadLibrary(), 里边填的是后面咱们那些cpp代码要通过Android.mk编成的so库的名字,如我这由于命名为libdraw.so,所以填的draw . 

2. 使用javac 生成 .class文件 

3. 使用javah 解析.class生成 .h文件 

 坑1: 这边需要注意执行javah的路径为 app/src/main/java, 后面跟的是包名+类名,

生成的.h长的样子如下: 

com_example_test1_Draw.h

//com_example_test1_Draw.h


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

#ifndef _Included_com_example_test1_Draw
#define _Included_com_example_test1_Draw
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_test1_Draw
 * Method:    initImpl
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_example_test1_Draw_initImpl
  (JNIEnv *, jobject);

/*
 * Class:     com_example_test1_Draw
 * Method:    resizeImpl
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_example_test1_Draw_resizeImpl
  (JNIEnv *, jobject);

/*
 * Class:     com_example_test1_Draw
 * Method:    doDrawImpl
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_example_test1_Draw_doDrawImpl
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

4. 创建jni文件夹, 创建cpp文件

鼠标选中app 文件夹, 然后 File ==> New ==> Folder ==> Jni Folder ,

然后路径选 src/main/jni, 如下: 

创建完后如下, 是个空文件夹, 接着咱们再来创建.cpp文件, 添加编译脚本

 

里边添加个.cpp文件,根据自己需求含义命名,如我这边的Draw.cpp , 

然后把整个前面生成的.h内容拷贝过来, 往函数里边添加实现,写完该.h可以不要了, 如我这边添加的Draw.cpp 

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <android/log.h>


#define TAG "======>lkh" 
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__) // 定义LOGD类型
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__) // 定义LOGI类型
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__) // 定义LOGW类型
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__) // 定义LOGE类型
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__) // 定义LOGF类型

/* Header for class com_example_test1_Draw */

#ifndef _Included_com_example_test1_Draw
#define _Included_com_example_test1_Draw
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_test1_Draw
 * Method:    initImpl
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_example_test1_Draw_initImpl
  (JNIEnv *, jobject) {
        LOGI("Java_com_example_test1_Draw_initImpl");
  }

/*
 * Class:     com_example_test1_Draw
 * Method:    resizeImpl
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_example_test1_Draw_resizeImpl
  (JNIEnv *, jobject) {
    LOGI("Java_com_example_test1_Draw_resizeImpl");
  }

/*
 * Class:     com_example_test1_Draw
 * Method:    doDrawImpl
 * Signature: ()V
 */
 static bool printLogFirstTime = false;
JNIEXPORT void JNICALL Java_com_example_test1_Draw_doDrawImpl
  (JNIEnv *, jobject) {
  if (printLogFirstTime == false) {
    LOGI("Java_com_example_test1_Draw_doDrawImpl");
    printLogFirstTime  = true;
   }

  }

#ifdef __cplusplus
}
#endif
#endif

  

5.  添加 Android.mk, Application.mk 

jni目录下添加编cpp的mk文件,

Android.mk , 我这要生成叫libdraw.so的库所以LOCAL_MODULE 赋值 draw.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := draw
LOCAL_SRC_FILES := Draw.cpp
LOCAL_LDLIBS += -llog
LOCAL_LDLIBS += -lGLESv2
# use GL ext model
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES


include $(BUILD_SHARED_LIBRARY)

 Application.mk 

APP_ABI := all
APP_PLATFORM := android-17

其中, 17根据自己的实际情况需求版本调

6. 使用ndk-build 编译  生成.so

jni目录下使用ndk-build编译生成.so文件, 如下:  

 如果报这个错 

Android NDK: WARNING: APP_PLATFORM android-17 is higher than android:minSdkVersion 1 in

通过在AndroidManifest.xml 添加如下代码解决, 
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23"/>

其中, 17, 23 根据自己的实际情况需求版本调

7. 添加 各种ndk配置

build.gradle 添加 so打包路径, 不添加的话so没打包进去,apk一跑到jni代码就crash了,报找不到so库错误,

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

gradle.properties 添加 

android.useDeprecatedNdk=true

local.properties 添加  ndk路径 

ndk.dir=/home/XXX/Android/Sdk/ndk-bundle


 

8.make project, run 哈哈哈

猜你喜欢

转载自blog.csdn.net/goodnight1994/article/details/122103512