首页 > 解决方案 > 本机 JNI 文件在 Android Studio 中找不到 Java 文件的路径

问题描述

我在 android studio 中有一个本地 C 文件,我用它来生成带有 JNI 的库。但是当我运行应用程序时,我收到文件错误,找不到 java 文件。所以 C 文件有一个指向 java 文件的指针,该指针使用该文件的路径。这就是我遇到的问题。我想,我没有提供正确的路径。这是在Windows机器中。这是错误。

A/zygote: java_vm_ext.cc:504] JNI DETECTED ERROR IN APPLICATION: JNI RegisterNatives called with pending exception java.lang.ClassNotFoundException: Didn't find class "java.org.techgeorge.tracehost.Tracepath" on path: DexPathList[[zip file "/data/app/org.techgeorge.tracehost-W_AzDnbsP-K7alPTKabP6Q==/base.apk", zip  file "/data/app/org.tech

我认为这是失败的代码部分

jclass kClass = (*env)->FindClass(env, "java/org/techgeorge/tracehost/Tracepath");

这是文件

#include "org_techgeorge_tracehost_Tracepath.h"
#include <jni.h>
#include <unistd.h>
#include "tracepath.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <arpa/inet.h>



typedef struct {
    jobject gObject;

    JNIEnv * g_Env;

    jclass kClass;

    jmethodID  updateMethodId;

    jmethodID  endMethodId;

} Nofication;

Nofication nofication;

JNIEXPORT void JNICALL beginTrace(JNIEnv *env, jobject object, jstring path){
    nofication.gObject = object;
    nofication.g_Env = env;

    nofication.kClass = (*env)->FindClass(env, "java/org/techgeorge/tracehost/Tracepath");
    nofication.updateMethodId = (*env)->GetMethodID(env, nofication.kClass, "callback", "(Ljava/lang/String;)V");
    nofication.endMethodId = (*env)->GetMethodID(env, nofication.kClass, "end", "()V");

    jboolean tmp = 1;
    const char * domin = (*env)->GetStringUTFChars(env, path, &tmp);

    struct hostent* host = gethostbyname(domin);
    if(host){
        notifyUpdateToJava("To %s ",  host->h_name);

        for (;;){
            if (*host->h_aliases){
                notifyUpdateToJava("(%s )",  *host->h_aliases);
                host->h_aliases++;
            } else {
                break;
            }
        }

        for (;;){
           if (*host->h_addr_list){
               notifyUpdateToJava("(%s )",  inet_ntoa(*(struct in_addr*)(*host->h_addr_list)));
               host->h_addr_list++;
           } else {
               break;
           }
        }

//        notifyUpdateToJava(" %s ",  inet_ntoa(*(struct in_addr*)(host->h_addr_list[1])));
        notifyUpdateToJava("\n");
    } else {
        notifyUpdateToJava("Net error! %s\n", strerror(errno));
        notifyEnd();
    }

    LOGD(domin);
    char * ret[] = {"tracepath", domin};
    traceroute(2, ret);
    LOGD(strerror(errno));
//
}

char line[1000];
int notifyUpdateToJava(const char* logs, ...){
    int ret = 0;
    char value[200];
    va_list arg;
    va_start(arg, logs);
    ret = vsprintf(value, logs, arg);
    va_end(arg);

    strcat(line, value);
    if(value[strlen(value) - 1] == '\n'){
        LOGD(line);
        if (line){
            jstring value = (*nofication.g_Env)->NewStringUTF(nofication.g_Env, line);
            (*nofication.g_Env)->CallVoidMethod(nofication.g_Env, nofication.gObject, nofication.updateMethodId, value);
        }
        memset(line, 0, sizeof(line));
    }

    return ret;
}

void notifyEnd(){
    (*nofication.g_Env)->CallVoidMethod(nofication.g_Env, nofication.gObject, nofication.endMethodId);
}

static const JNINativeMethod gMethods[] = {
        {"beginTrace", "(Ljava/lang/String;)V", (void*)beginTrace}
};

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
    LOGD("jni load");
    JNIEnv *env;
    if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK){
        return -1;
    }

    jclass kClass = (*env)->FindClass(env, "java/org/techgeorge/tracehost/Tracepath");
    (*env)->RegisterNatives(env, kClass, gMethods, sizeof(gMethods) / sizeof(gMethods[0]));
    return JNI_VERSION_1_4;
}

JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved){
    LOGD("jni unload");
}

标签: javaandroidcjava-native-interface

解决方案


应该是FindClass(env, "org/techgeorge/tracehost/Tracepath")。屏幕截图中的这个javasourceroot,而不是包名称的一部分。


推荐阅读