0

I am trying to create an ArrayList that contains a Java class by calling its methods using a native function. The java class ExampleClass looks as such:

public class ExampleClass {
    private int _exampleID;
    private String _exampleName;
    public ExampleClass(int exampleID, String exampleName) {
        _exampleID = exampleID;
        _exampleName = exampleName;
    }
}

On the native side I have a complimentary class ExampleClass_Cpp which is loaded into a vector. Here is the native implementation:

static thread_local JNIEnv* env;
static jclass java_util_ArrayList = static_cast<jclass>(env->NewGlobalRef(env->FindClass("java/util/ArrayList")));
static jmethodID java_util_ArrayList_= env->GetMethodID(java_util_ArrayList, "<init>", "(I)V");
jmethodID java_util_ArrayList_add = env->GetMethodID(java_util_ArrayList, "add", "(Ljava/lang/Object;)V");

JNIEXPORT jobject JNICALL cppv2javaAL(JNIEnv *env) {

    std::vector<ExampleClass_Cpp> vector;
    jclass J_Class_Example = env->FindClass("app/androidndkproject/ExampleClass");
    jmethodID methodId = env->GetMethodID(J_Class_Example, "<init>", "(I)V");

    jobject result = env->NewObject(java_util_ArrayList, java_util_ArrayList_, vector.size());
    for (auto const &Ex: vector) {
        jobject J_Obj_Example = env->NewObject(J_Class_Example, methodId, Ex.getExampleID(), Ex.getExampleName());
        env->CallVoidMethod(result, java_util_ArrayList_add, J_Obj_Example);
        env->DeleteLocalRef(J_Obj_Example);
    }
    return result;
}

I am having some difficulty with the corresponding JNI mapping. My present Java call, which I know is incorrect is as follows : public native ArrayList<ExampleClass> cpp2java();.

What is the proper way to create an ArrayList through the JNI (or what is wrong with the above)? Should it be jobjectArray?

If it was written in Java (the context I would like to use it) it would be:

public List<ExampleClass> exampleList = new ArrayList<ExampleClass>();

Thanks in advance.

1 Answer 1

1

First, ArrayList.add() returns boolean, you should use

CallBooleanMethod

Maybe there is a better way, but from my experience, you can

create an empty list in java

public List<ExampleClass> exampleList = new ArrayList<ExampleClass>()

pass exampleList as a reference to cpp, sth like:

JNIEXPORT jobject JNICALL cppv2javaAL(JNIEnv *env, jobject jlist) {
...
env->CallBooleanMethod(jlist, java_util_ArrayList_add, J_Obj_Example);
...
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the input. How would you call to cppv2javaAL in Java? (public native ...?... cppv2javaAL(exampleList);
yes, just create a native java method that mapps cppv2javaAL
How in the world do you declare ** java_util_ArrayList** in JNI?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.