jfieldID对对象

时间:2017-04-20 02:30:44

标签: java android c++ java-native-interface

我的MainActivity.java:

 package com.example.android.testjni;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {
    final String TAG = "TestJni";
    static {
        System.loadLibrary("addjni");
        native_init();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //wrong
        native_setup();
        Log.i(TAG, "add from jni:"+native_add(3,21));
    }

    private long mNativeMainA;
    private native final int native_add(int a, int b);
    private static native final void native_init();
    private static native final void native_setup();
}

我的JNI代码,MainActivity_jni.cpp:

#include <jni.h>
#include <stdint.h>
#include <sys/types.h>
#include <android/log.h>
#include "MainActivity.h"
#define LOGV(...) { __android_log_print(ANDROID_LOG_INFO, "TestJni+++++++", __VA_ARGS__); }

struct fields_t {
    // these fields provide access from C++ to the...
    jclass    clazzMainA;          // AudioEffect class
    jfieldID  fidMainA; // stores in Java the native AudioEffect object
};
static fields_t fields;
static const char* const kClassPathName = "com/example/android/testjni/MainActivity";

static void com_example_native_init(JNIEnv *env)
{
    // Get the AudioEffect class
    jclass clazz = env->FindClass(kClassPathName);
    if (clazz == NULL) {
        LOGV("Can't find %s", kClassPathName);
        return;
    }

    fields.clazzMainA = (jclass)env->NewGlobalRef(clazz);

    fields.fidMainA = env->GetFieldID(
            fields.clazzMainA,
            "mNativeMainA", "J");
    if (fields.fidMainA == NULL) {
        LOGV("Can't find fidMainA.%s", "mNativeMainA");
        return;
    }
    LOGV("native init over!");
}

static void com_example_native_setup(JNIEnv *env, jobject thiz)
{
    MainActivity *lpMainA = new MainActivity();
    LOGV("native setup!lpMainA=0x%lx,status=%d", (jlong)(lpMainA), lpMainA->mStatus);
    env->SetLongField(thiz, fields.fidMainA, (jlong)(lpMainA));//here wrong
}

static long getlpMainA(JNIEnv *env, jobject thiz)
{
    jlong lpmaina = env->GetLongField(thiz, fields.fidMainA);
    return lpmaina;
}
static int com_example_native_add(JNIEnv *env, jobject thiz,jint a, jint b)
{
    LOGV("native add!a=%d,b=%d",a,b);
    //com_example_native_setup(env,thiz);//here will be ok!
    MainActivity *lpMainA = (MainActivity *)getlpMainA(env, thiz);
    LOGV("native add!lpMainA=0x%lx,status=%d", (jlong)lpMainA, lpMainA->mStatus);

    return a+b;
}

// Dalvik VM type signatures
static const JNINativeMethod gMethods[] = {
    {"native_init",          "()V",      (void *)com_example_native_init},
    {"native_add",           "(II)I",    (void *)com_example_native_add},
    {"native_setup",         "()V",      (void *)com_example_native_setup}
};

jint JNI_OnLoad(JavaVM* vm, void* reserved __unused)
{
    JNIEnv* env = NULL;
    jint result = -1;
    jclass clazz;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        LOGV("ERROR: GetEnv failed\n");
        goto bail;
    }
    clazz = env->FindClass(kClassPathName);
    if(clazz == NULL) {
        LOGV("find class error!");
        goto bail;
    }
    env->RegisterNatives(clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0]));

    result = JNI_VERSION_1_4;
bail:
    return result;
}

我的MainActivity.cpp:

//
// Created by android on 17-4-19.
//
#include "MainActivity.h"
MainActivity::MainActivity()
{
mStatus = 100;
}

当我在MainActivity.java中调用native_setup时,它会给出以下错误:

04-20 02:07:02.505 26064 26064 I TestJni+++++++: native init over!
04-20 02:07:02.522 26064 26064 W art     : Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
04-20 02:07:02.576 26064 26064 I TestJni+++++++: native setup!lpMainA=0x790e761e70,status=100
04-20 02:07:02.588 26064 26064 F art     : art/runtime/java_vm_ext.cc:470] JNI DETECTED ERROR IN APPLICATION: jfieldID long com.example.android.testjni.MainActivity.mNativeMainA not valid for an object of class java.lang.Class<com.example.android.testjni.MainActivity>
04-20 02:07:02.588 26064 26064 F art     : art/runtime/java_vm_ext.cc:470]     in call to SetLongField
04-20 02:07:02.588 26064 26064 F art     : art/runtime/java_vm_ext.cc:470]     from void com.example.android.testjni.MainActivity.native_setup()

.....

但如果我从com_example_native_setup调用com_example_native_add,一切都会正确。我真的很困惑。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

解决了它: 我不应该将native_setup声明为静态。