我的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
,一切都会正确。我真的很困惑。
任何帮助将不胜感激!
答案 0 :(得分:0)
解决了它:
我不应该将native_setup
声明为静态。