2017-04-20 112 views
0

我MainActivity.java:jfieldID无效对象

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_add调用com_example_native_setup,一切都会是正确的。我很困惑。

任何帮助将不胜感激!

回答

0

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