简体   繁体   English

在Android Studio 3中设置JNI

[英]Setting up JNI in Android Studio 3

I am using JNI in an Android Studio project I am working on. 我正在我正在开发的Android Studio项目中使用JNI。 Currently, I have a C++ library that looks similar to this. 当前,我有一个看起来与此相似的C ++库。

#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);
    }
}

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. 每次运行时,rectClass必须重新引用该类,并且每次调用FindFeatures函数时,都必须重新计算和重新定义程序中保持不变的其他变量。

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. 在Stack Overflow上遇到了这个答案 (除了它显示了我要执行的操作这一事实以外,它与这个问题无关),它显示了使用JNI时本机文件的不同布局。

It looked like this 看起来像这样

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. 这显示了一个本地文件,其中包含昂贵且恒定的变量,这些变量似乎仅被声明和计算一次。

How can I achieve a similar thing using only the Android Studio IDE? 仅使用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. 我不介意在Android Studio IDE设置中设置外部工具,但是我不想每次编译代码时都在Android Studio和CMD之类之间不断切换。

Ideally, this could all be handled correctly when Make Project is hit. 理想情况下,在单击Make Project时,所有这些都可以正确处理。 Is this possible in Android Studio 3? Android Studio 3有可能吗?

You are 100% right, some JNI values beg to be cached and reused. 您是100%正确的,有些JNI值将被缓存和重用。 Class references and method IDs are good examples. 类引用和方法ID是很好的例子。 Please remember that FindClass() returns a local reference, so you need NewGlobalRef() for each class you keep in cache. 请记住, FindClass()返回本地引用,因此对于缓存中保留的每个类,您都需要NewGlobalRef()

Android Studio does not help us with this setup, and I am not aware of reliable tools that can do such refactoring for us. Android Studio无法帮助我们进行此设置,并且我不知道可以为我们进行此类重构的可靠工具。 You can learn good practices from open source code, eg from WebRTC JNI wrapper or from Spotify JNI helpers . 您可以从开源代码(例如WebRTC JNI包装器Spotify JNI帮助 器)中学习良好做法。

Android Studio can only keep track of the native methods, not of the cached objects, conversions, etc. Android Studio只能跟踪本机方法,而不能跟踪缓存的对象,转换等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM