java - 本机 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");
}
解决方案
应该是FindClass(env, "org/techgeorge/tracehost/Tracepath")
。屏幕截图中的这个java是sourceroot,而不是包名称的一部分。
推荐阅读
- python - 如何在 docker 容器中使用本地文件?
- testing - 如何使用请求在 JEST 中测试异步调用而不使用模拟和等待反应钩子测试库
- angular - Firebase 经过身份验证的用户,但没有权限
- python - 无法在 PyQt5 中打印点击的行
- excel - 如何拒绝 application.inputbox 中的符号
- c++ - 了解 Getline 函数
- webpack - Livereload 服务器导致 ERR:CONNECTION REFUSED
- javascript - 使用条件 mongodb 在数组中检索对象
- php - 数据库是完整的问号而不是mysql中的俄语单词
- c++ - 定义“.h”文件的相对路径(C++/Arduino)