You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Android Studio 3中配置JNI及相关C++代码实现咨询

Hey there! Let's walk through both the JNI setup in Android Studio and the key technical points from your C++ snippet to help you get things running smoothly.

Android Studio JNI 配置步骤

Since you're using OpenCV alongside JNI, we'll cover the full setup tailored to that stack:

1. Set up NDK and CMake

  • Open your project in Android Studio, go to File > Project Structure > SDK Tools.
  • Check NDK (Side by side) and CMake, then click "Apply" to install them. Android Studio will auto-configure paths in local.properties for you.

2. Configure CMakeLists.txt

Create a CMakeLists.txt file in your app module root (same level as build.gradle) with these contents:

cmake_minimum_required(VERSION 3.22.1)
project("cerbyarms-features")

# Compile your native C++ code into a shared library
add_library(
    native-features
    SHARED
    src/main/cpp/your-native-file.cpp  # Replace with your actual .cpp file path
)

# Link OpenCV (critical since you're using Rect from OpenCV)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(native-features ${OpenCV_LIBS})

# Link Android's log library for debugging
find_library(
    log-lib
    log
)
target_link_libraries(native-features ${log-lib})

3. Update Module-level build.gradle

Add the external native build config to your app's build.gradle (Module level) under the android block:

android {
    ...
    defaultConfig {
        ...
        externalNativeBuild {
            cmake {
                cppFlags "-std=c++17"  # Match your C++ version
                abiFilters 'arm64-v8a', 'armeabi-v7a'  # Match OpenCV's supported ABIs
            }
        }
    }
    externalNativeBuild {
        cmake {
            path file('CMakeLists.txt')
            version '3.22.1'  # Match your installed CMake version
        }
    }
}

In your CameraActivity Java class, declare the native method to match your C++ function signature:

import org.opencv.core.Rect;

public class CameraActivity extends AppCompatActivity {
    // Load the shared library first
    static {
        System.loadLibrary("native-features");  // Name matches add_library in CMakeLists.txt
    }

    // Native method declaration
    public native Rect FindFeatures(long maskMat);
}
Your C++ Code Technical Analysis

Looking at your snippet, here are key fixes and best practices to avoid crashes and bugs:

1. Validate OpenCV Mat Pointer

Your maskMat parameter is a jlong pointing to an OpenCV Mat object. First, safely cast and validate it:

#include <jni.h>
#include <opencv2/core/core.hpp>
#include <android/log.h>

// Debug logging helper
#define LOG_TAG "JNI-Features"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

extern "C" {
JNIEXPORT jobject JNICALL Java_com_cerbyarms_cerbyarms_esra_camera_CameraActivity_FindFeatures(JNIEnv* env, jobject thiz, jlong maskMat) {
    // Cast jlong to Mat* and validate
    cv::Mat* mask = reinterpret_cast<cv::Mat*>(maskMat);
    if (!mask || mask->empty()) {
        LOGD("Invalid or empty mask Mat");
        return nullptr;
    }

    // ... Your feature detection logic here to get x, y, width, height ...
    int x = 0, y = 0, width = 100, height = 100; // Example values

2. Safe JNI Object Creation with Error Checking

When creating the Rect object, add error checks to handle missing classes/methods and manage local references:

// Find Rect class
    jclass rectClass = env->FindClass("org/opencv/core/Rect");
    if (!rectClass) {
        LOGD("Failed to find Rect class");
        env->ExceptionClear(); // Clear pending exception to avoid app crash
        return nullptr;
    }

    // Get Rect constructor method ID (signature for (int,int,int,int))
    jmethodID rectCtor = env->GetMethodID(rectClass, "<init>", "(IIII)V");
    if (!rectCtor) {
        LOGD("Failed to find Rect constructor");
        env->ExceptionClear();
        env->DeleteLocalRef(rectClass); // Clean up local reference
        return nullptr;
    }

    // Create Rect object
    jobject rectObj = env->NewObject(rectClass, rectCtor, (jint)x, (jint)y, (jint)width, (jint)height);
    
    // Clean up local references to avoid memory leaks
    env->DeleteLocalRef(rectClass);

    return rectObj;
}
}

3. Critical Notes

  • extern "C" is mandatory: You already have this, which prevents C++ name mangling so JNI can locate your function correctly. Don't remove it!
  • ABI Consistency: Ensure the ABIs you specify in build.gradle match those provided by your OpenCV SDK. Mismatches will cause runtime crashes.
  • Local Reference Management: JNI has a limit on local references. Always call DeleteLocalRef on objects like jclass when you're done with them.

内容的提问来源于stack exchange,提问作者Dan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:40:16