Android studio JNI開発

8259 ワード

先日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);

}

2つのメソッドを定義しました.それぞれパッケージとテストメソッドです.このクラスファイルをコンパイルし、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に変更する必要があります.