在Android Studio 3中设置JNI [英] Setting up JNI in Android Studio 3

查看:75
本文介绍了在Android Studio 3中设置JNI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在正在处理的Android Studio项目中使用JNI.当前,我有一个与此类似的C ++库.

I am using JNI in an Android Studio project I am working on. Currently, I have a C++ library that looks similar to this.

#include <jni.h>
...
extern "C" {
    JNIEXPORT jobject JNICALL Java_com_cerbyarms_cerbyarms_esra_camera_CameraActivity_FindFeatures(JNIEnv* env, jobject, jlong maskMat)
    {
        ...
        jclass rectClass = env->FindClass("org/opencv/core/Rect");
        jmethodID rectID = env->GetMethodID(rectClass, "<init>", "(IIII)V");
        return env->NewObject(rectClass, rectID, x, y, width, height);
    }
}

这有效.但是,它效率低下.每次运行时,rectClass必须重新引用该类,并且每次调用函数FindFeatures时,都必须重新计算和重新定义程序中保持不变的其他变量.

This works. However, it is inefficient. Every time this is run, rectClass has to refind the class and other variables that remain constant in the program have to be recalculated and redefined every time function FindFeatures is called.

我遇到了关于堆栈溢出的这个答案(除了它显示的事实之外,它与这个问题无关我正在尝试做的一个示例),显示了使用JNI时本机文件的不同布局.

I came across this answer on Stack Overflow (It is not related to this question apart from the fact that it shows an example of what I am trying to do), that shows a different layout for a native file when using JNI.

看起来像这样

static jclass java_util_ArrayList;
static jmethodID java_util_ArrayList_;
jmethodID java_util_ArrayList_size;
jmethodID java_util_ArrayList_get;
jmethodID java_util_ArrayList_add;
static thread_local JNIEnv* env;

void init() {
    java_util_ArrayList      = static_cast<jclass>(env->NewGlobalRef(env->FindClass("java/util/ArrayList")));
    java_util_ArrayList_     = env->GetMethodID(java_util_ArrayList, "<init>", "(I)V");
    java_util_ArrayList_size = env->GetMethodID (java_util_ArrayList, "size", "()I");
    java_util_ArrayList_get  = env->GetMethodID(java_util_ArrayList, "get", "(I)Ljava/lang/Object;");
    java_util_ArrayList_add  = env->GetMethodID(java_util_ArrayList, "add", "(Ljava/lang/Object;)Z");
}

std::vector<std::string> java2cpp(jobject arrayList) {
    jint len = env->CallIntMethod(arrayList, java_util_ArrayList_size);
    std::vector<std::string> result;
    result.reserve(len);
    for (jint i = 0; i < len; i++) {
        jstring element = static_cast<jstring>(env->CallObjectMethod(arrayList, java_util_ArrayList_get, i));
        const char* pchars = env->GetStringUTFChars(element, nullptr);
        result.emplace_back(pchars);
        env->ReleaseStringUTFChars(element, pchars);
        env->DeleteLocalRef(element);
    }
}

这显示了一个本地文件,其中包含昂贵且常量的变量,这些变量似乎仅被声明和计算一次.

This shows a native file that has expensive and constant variables that appear to only be declared and calculated once.

仅使用Android Studio IDE如何实现类似的目的?我不介意在Android Studio IDE设置中设置外部工具,但我不想每次编译代码时都在Android Studio和CMD之类之间不断切换.

How can I achieve a similar thing using only the Android Studio IDE? I don't mind having to set up external tools in the Android Studio IDE settings, but I don't want to have keep switching between Android Studio and something like CMD every time I compile my code.

理想情况下,按Make Project可以正确处理所有问题.在Android Studio 3中有可能吗?

Ideally, this could all be handled correctly when Make Project is hit. Is this possible in Android Studio 3?

推荐答案

您是100%正确的,有些JNI值请求缓存和重用.类引用和方法ID是很好的例子.请记住, FindClass()返回本地引用,因此对于缓存中保留的每个类,您都需要 NewGlobalRef().

You are 100% right, some JNI values beg to be cached and reused. Class references and method IDs are good examples. Please remember that FindClass() returns a local reference, so you need NewGlobalRef() for each class you keep in cache.

Android Studio不能帮助我们进行此设置,并且我不知道可以为我们进行此类重构的可靠工具.您可以从开源代码中学习良好做法,例如从 WebRTC JNI包装器或从 Spotify JNI帮助器.

Android Studio does not help us with this setup, and I am not aware of reliable tools that can do such refactoring for us. You can learn good practices from open source code, e.g. from WebRTC JNI wrapper or from Spotify JNI helpers.

Android Studio只能跟踪本机方法,而不能跟踪缓存的对象,转换等.

Android Studio can only keep track of the native methods, not of the cached objects, conversions, etc.

这篇关于在Android Studio 3中设置JNI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆