Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/214.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Android Studio 3中设置JNI_Java_Android_C++_Android Studio_Java Native Interface - Fatal编程技术网

Java 在Android Studio 3中设置JNI

Java 在Android Studio 3中设置JNI,java,android,c++,android-studio,java-native-interface,Java,Android,C++,Android Studio,Java Native Interface,我正在Android Studio项目中使用JNI。目前,我有一个类似于这个的C++库。 #include <jni.h> ... extern "C" { JNIEXPORT jobject JNICALL Java_com_cerbyarms_cerbyarms_esra_camera_CameraActivity_FindFeatures(JNIEnv* env, jobject, jlong maskMat) { ... jcl

我正在Android Studio项目中使用JNI。目前,我有一个类似于这个的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);
    }
}
这显示了一个本机文件,其中包含昂贵的常量变量,这些变量只能声明和计算一次

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


理想情况下,当点击
makeproject
时,这一切都可以正确处理。这在Android Studio 3中可能吗?

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

Android Studio不能帮助我们进行这种设置,我也不知道有什么可靠的工具可以为我们进行这种重构。您可以从开源代码中学习良好的实践,例如从或


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

“如何仅使用Android Studio IDE实现类似的功能?”我认为我不理解这个问题。为什么不能从Android工作室中创建一个新的.CPP文件,并编写你想要的C++代码?@米迦勒,我是JNI的新手,如果它是显而易见的,那么抱歉,但是如果我在A.CPP文件中写了我想要的C++代码,那么我将如何访问java文件中的代码。从问题中的例子来看,我如何访问Java文件中的java2cpp?通过实现和导出合适的函数,就像您展示的第一段代码一样。当然,您的Java代码不知道什么是
std::vector
,因此您必须返回一个
jobject
jobjectArray
来表示一个
String[]
List
。谢谢,
NewGlobalRef
正是我所需要的。此外,这些链接将是有用的,因为我以前从未做过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);
    }
}