Android studio JNI开发

前些天要写Android 双摄打包工作,由于任务紧,要实现调用底层so库功能 ,因此需要写jni来实现。

如下:

1.先应用需要导入so库,定义方法

public class Compress {
    static {
        System.loadLibrary("compress_jni");
    }

    public   native static byte[] compress(byte[] pBokeh,byte[] pMain,byte[] pDepth);
    public   native static String test(byte[] pBokeh,byte[] pMain,byte[] pDepth,int lBoken,int lMain,int lDepth);

}

定义了两个方法 分别是打包和测试方法 ,现在需要生成编译这个类文件和生成jni头文件,在android studio 使用

javac 路径/Compress.java 。

然后生成Jni头文件

javah -jni 包名.Compress

注意以上路径不要写错

2.编写JNI

生成了头文件,写个Compress.cpp文件 将头文件的内容复制到Compress.cpp文件 ,然后将定义的方法改写并实现就可以了。

#include 
#include 
#include "libDepthBokehEffectBase.h"
//#include "FileUtil.h"
/* Header for class com_xthinks_myapplication_Compress */

#ifndef _Included_com_mediatek_camera_feature_mode_vsdof_Compress
#define _Included_com_mediatek_camera_feature_mode_vsdof_Compress
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jbyteArray JNICALL Java_com_mediatek_camera_feature_mode_vsdof_Compress_compress
  (JNIEnv *env, jclass jobj, jbyteArray Bokeh , jbyteArray Main, jbyteArray Depth,int Lboken){

    BstJpgCompressData mpo;
    mpo.pBokehBuffer = (uint8_t *) env->GetByteArrayElements(Bokeh, 0);
    mpo.pMainBuffer = (uint8_t *) env->GetByteArrayElements(Main, 0);
    mpo.pDepth = (uint8_t *) env->GetByteArrayElements(Depth, 0);
    mpo.lBokeh =(jint) env->GetArrayLength(Bokeh);
    mpo.lMain = (jint) env->GetArrayLength(Main);
    mpo.lDepth =(jint) env->GetArrayLength(Depth);
    uint8_t *compressed = nullptr;
    uint32_t compressed_len = 0;
    int res = bst_jpg_compress(&mpo, &compressed, &compressed_len);
     if (res == 0 && compressed != nullptr) {
        jbyteArray jarr = env->NewByteArray(compressed_len);
        env->SetByteArrayRegion(jarr, 0, compressed_len, (jbyte*)compressed);
        delete[] compressed;
        return jarr;
    } else {
        return NULL;
    }
            // compressed buffer is in "compressed"
                  // compressed buffer len is "compressed_len"

                  // 用完了buffer后要delete




   // bst_jpg_compress(&mpo, uint8_t** out, uint32_t* lOut);
    //int res = bst_jpg_compress(&mpo, "test.jpg");



  }

    /*
     * Class:     com_xthinks_myapplication_Compress
     * Method:    test1
     * Signature: ([B[B[B)Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_com_mediatek_camera_feature_mode_vsdof_Compress_test
      (JNIEnv *env, jclass jobj, jbyteArray Bokeh , jbyteArray Main, jbyteArray Depth,jint Lboken,jint Lmain,jint Ldepth){
             BstJpgCompressData mpo;
             mpo.pBokehBuffer = (uint8_t*) env->GetByteArrayElements(Bokeh, 0);
             mpo.pMainBuffer = (uint8_t*)env->GetByteArrayElements(Main, 0);
             mpo.pDepth =(uint8_t*) env->GetByteArrayElements(Depth, 0);
             mpo.lBokeh=Lboken;
             mpo.lMain=Lmain;
             mpo.lDepth=Ldepth;
             int res = bst_jpg_compress(&mpo, "/sdcard/Pictures/test.jpg"); 
             char array[30];
             snprintf(array,30,"jni accept num : %d",res);       
             return env->NewStringUTF(array);
      }

#ifdef __cplusplus
}
#endif
#endif

注意
由于代码中使用了第三方的so库,因此会出现编译异常,如果不需要调用第三方so库的话 ,很简单 配置NDK,

打开app Module的build.gradle文件,在defaultConfig节点里添加以下代码
注意这里的moduleName,是我们在之前自己编写的类里面加载的so库名
 ndk {
            moduleName "jniCompress"
            ldLibs "log", "z", "m"
            abiFilters "armeabi", "armeabi-v7a", "x86"
        }

还要在gradle.properties里面加上这么一句话:
android.useDeprecatedNdk=true

然后编译一下 将 生成了so文件放代码在目录,重新打包编译就可以了。

3.调用第三方so库编译。
曾经搜了很多种方法 都没有编译通过 ,老是报无法匹配该方法,因此就没有使用Android studio编译了 用ubantu环境编译,因此需要写mk文件,单独编译jni,将应用单独编译,然后包含jni的mk文件就可以了 。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libDepthBokehEffectBase
LOCAL_MODULE_CLASS = SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX = .so
LOCAL_PROPRIETARY_MODULE = true
LOCAL_MODULE_TAGS = optional
LOCAL_SHARED_LIBRARIES_64 = libc++
LOCAL_MULTILIB = 64
LOCAL_SRC_FILES := libDepthBokehEffectBase.so
include $(BUILD_PREBUILT)

include $(CLEAR_VARS)
LOCAL_MODULE := libcompress_jni
LOCAL_SRC_FILES := Compress.cpp
LOCAL_MULTILIB = 64
LOCAL_MODULE_TAGS := optional
LOCAL_SHARED_LIBRARIES := libDepthBokehEffectBase
include $(BUILD_SHARED_LIBRARY)

注意编译生成的是64位so库
如果要生成32位的话 需要将64改为32就可以了。

你可能感兴趣的:(Android)