Android jni JNI_OnLoad错误

时间:2015-04-26 04:42:29

标签: android-ndk java-native-interface

apiaccess.h

#include <jni.h>
#ifndef APIACCESS_H
#define APIACCESS_H
void init_data(JNIEnv* env);
void toast(char* msg);
#endif

您好-jni.c

#include <string.h>
#include <jni.h>
#include "apiaccess.h"

jstring javastr( JNIEnv* env, jobject        thiz );
void connectfunc(JNIEnv* env){
    JNINativeMethod methods[] = 
{{ "stringFromJNI", "()Ljava/lang/String;", (void*)javastr}};
  jclass clazz = (*env)->FindClass(env, "com/testndk/ndk/HelloJni");
    int status = ((*env)->RegisterNatives(env, clazz, methods, 1));
}
jint JNI_OnLoad(JavaVM *vm, void *reserved){
    // Get JNI Env for all function calls
    JNIEnv* env = NULL;
    if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6) != JNI_OK) return -1;
    connectfunc(env);
    init_data(env);
    toast("Toast in JNI_OnLoad"); //error
    //return jni version that we need.   default valur is jni 1.1
    return JNI_VERSION_1_6;
}

jstring javastr( JNIEnv* env, jobject thiz ){  
     toast("Toast in javastr");//no error
     return (*env)->NewStringUTF(env,   "Hello from JNI !");
 }

apiaccess.c

#include <jni.h>

JNIEnv* env = 0;
void init_data(JNIEnv* parenv){
    env = parenv;
}
void toast(char* msg){
    static jclass clazz = 0;
    if(clazz==0)  clazz = (*env)->FindClass(env, "com/testndk/ndk/HelloJni");
    static jmethodID method = 0;
    if(method==0)  method = (*env)->GetStaticMethodID(env, clazz, "toast", "(Ljava/lang/String;)V");
    (*env)->CallStaticVoidMethod(env,clazz,method,(*env)->NewStringUTF(env, msg)); 
}

HelloJni.java

package com.testndk.ndk;

import android.app.*;
import android.content.*;
import android.os.*;
import android.widget.*;
import android.util.*;

public class HelloJni extends Activity{
private static Context ctx;
@Override
 public void onCreate(Bundle savedInstanceState)
 {
 super.onCreate(savedInstanceState);
   HelloJni.ctx = getApplicationContext();
        TextView  tv = new TextView(this);
        tv.setText(stringFromJNI());
        setContentView(tv);
    }
    public static void toast(String msg){
        Toast.makeText(HelloJni.ctx, msg,     Toast.LENGTH_SHORT).show();
    }
    public native String stringFromJNI();

    static {
        System.loadLibrary("hello-jni");
    }
}

在javastr中调用toast工作正常。但是在JNI_OnLoad中,它崩溃了应用程序。 为什么我不能在JNI_OnLoad()中调用toast? 我提供了与此错误相关的所有代码。 Logcat输出:

I/Timeline( 1558): Timeline:    Activity_launch_request    id:com.testndk.ndk time:14821530
V/ApplicationPolicy(  999):     isApplicationStateBlocked userId 0    pkgname com.testndk.ndk
D/ResourcesManager(  999): creating new AssetManager and set to /data/app/com.testndk.ndk-1/base.apk
I/ActivityManager(  999): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.testndk.ndk/.HelloJni} from uid 10008 on display 0
I/ActivityManager(  999): Start proc com.testndk.ndk for activity com.testndk.ndk/.HelloJni: pid=28993 uid=10281 gids={50281, 9997} abi=armeabi
I/SurfaceFlinger(  246): id=6131 createSurf (1080x1920),2 flag=404, Starting com.testndk.ndk
D/ResourcesManager(28993): creating new AssetManager and set to /data/app/com.testndk.ndk-1/base.apk
E/AndroidRuntime(28993): Process: com.testndk.ndk, PID: 28993
E/AndroidRuntime(28993):    at   com.testndk.ndk.HelloJni.toast(HelloJni.java:25)
E/AndroidRuntime(28993):    at com.testndk.ndk.HelloJni.<clinit>(HelloJni.java:30)
V/ApplicationPolicy(  999): isApplicationStateBlocked userId 0 pkgname com.testndk.ndk
W/ActivityManager(  999):   Force finishing activity com.testndk.ndk/.HelloJni
D/CrashAnrDetector(  999): processName: com.testndk.ndk
D/CrashAnrDetector(  999): broadcastEvent : com.testndk.ndk data_app_crash
I/SurfaceFlinger(  246): id=6132 createSurf (49x49),1 flag=4, Application Error: com.testndk.ndk
W/ActivityManager(  999): Activity pause timeout for   ActivityRecord{3a27a7c6 u0 com.testndk.ndk/.HelloJni t1692 f}
I/SurfaceFlinger(  246): id=6131 Removed Starting com.testndk.ndk (6/10)
I/SurfaceFlinger(  246): id=6131 Removed Starting com.testndk.ndk (-2/10)
I/ActivityManager(  999): Process com.testndk.ndk (pid 28993)(adj 9) has died(65,325)
I/SurfaceFlinger(  246): id=6132 Removed Application Error: com.testndk.ndk (7/9)
I/SurfaceFlinger(  246): id=6132 Removed Application Error: com.testndk.ndk (-2/9)
D/NetworkStatsFactory(  999): UpdateStatsForKnox

EDIT 我明白了问题所在。问题是在类加载时对System.LoadLibrary进行JNI_OnLoad调用和静态块调用。 所以ctx没有初始化并导致NullPointerException 我只是没有意识到静态块比构造函数

更早运行

0 个答案:

没有答案