- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想使用 dlib 库进行人脸检测,但它不适用于旧手机。
我因以下堆栈跟踪而崩溃:
E/AndroidRuntime( 4288): FATAL EXCEPTION: pool-1-thread-1
E/AndroidRuntime( 4288): java.lang.ExceptionInInitializerError
E/AndroidRuntime( 4288): at com.tzutalin.dlibtest.MainActivity.runDetectAsync(MainActivity.java:235)
E/AndroidRuntime( 4288): at com.tzutalin.dlibtest.MainActivity_.access$301(MainActivity_.java:34)
E/AndroidRuntime( 4288): at com.tzutalin.dlibtest.MainActivity_$6.execute(MainActivity_.java:158)
E/AndroidRuntime( 4288): at org.androidannotations.api.BackgroundExecutor$Task.run(BackgroundExecutor.java:405)
E/AndroidRuntime( 4288): at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
E/AndroidRuntime( 4288): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
E/AndroidRuntime( 4288): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
E/AndroidRuntime( 4288): at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:150)
E/AndroidRuntime( 4288): at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:264)
E/AndroidRuntime( 4288): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
E/AndroidRuntime( 4288): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
E/AndroidRuntime( 4288): at java.lang.Thread.run(Thread.java:856)
E/AndroidRuntime( 4288): Caused by: java.lang.NoSuchFieldError: no field with name='mLabel' signature='java/lang/String' in class Lcom/tzutalin/dlib/VisionDetRet;
E/AndroidRuntime( 4288): at com.tzutalin.dlib.PeopleDet.jniNativeClassInit(Native Method)
E/AndroidRuntime( 4288): at com.tzutalin.dlib.PeopleDet.<clinit>(PeopleDet.java:42)
E/AndroidRuntime( 4288): ... 12 more
因此,C 代码如下所示:
void JNIEXPORT DLIB_JNI_METHOD(jniNativeClassInit)(JNIEnv* env, jclass _this) {
jclass detRetClass = env->FindClass("com/tzutalin/dlib/VisionDetRet");
CHECK_NOTNULL(detRetClass);
gVisionDetRetOffsets.label =
env->GetFieldID(detRetClass, "mLabel", "java/lang/String");
gVisionDetRetOffsets.confidence =
env->GetFieldID(detRetClass, "mConfidence", "F");
gVisionDetRetOffsets.left = env->GetFieldID(detRetClass, "mLeft", "I");
gVisionDetRetOffsets.top = env->GetFieldID(detRetClass, "mTop", "I");
gVisionDetRetOffsets.right = env->GetFieldID(detRetClass, "mRight", "I");
gVisionDetRetOffsets.bottom = env->GetFieldID(detRetClass, "mBottom", "I");
gVisionDetRetOffsets.addLandmark =
env->GetMethodID(detRetClass, "addLandmark", "(II)Z");
if (gVisionDetRetOffsets.addLandmark == NULL) {
LOG(FATAL) << "Can't Find Method addLandmark(int,int)";
}
LOG(INFO) << "JniNativeClassIni Success";
}
以及相关的 Java 类:
public final class VisionDetRet {
private String mLabel;
private float mConfidence;
private int mLeft;
private int mTop;
private int mRight;
private int mBottom;
private ArrayList<Point> mLandmarkPoints = new ArrayList<>();
VisionDetRet() {
}
// Other code
}
因此,字段显然在这里,并且它获取类(CHECK_NOTNULL(detRetClass)
成功)。那么为什么它会在旧手机上崩溃呢? Google 帮不上什么忙,而且我对 NDK/JNI 的东西还很陌生。
P. S.Java文件是here C文件是here (是的,它们在 2 个不同的 repo 协议(protocol)中)
最佳答案
我不确定这对您在任何 Android 版本上的效果如何,因为 java/lang/String
是 GetFieldID
的错误签名。
对于类,签名应该是 L fully-qualified-class ;
,所以在你的情况下你需要 Ljava/lang/String;
关于android - GetFieldID 在 Android 4.4 及更早版本上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39915937/
我试图构建一个本地方法,虽然它似乎运行良好,但我很难理解函数中的字段 [*sig] - jfieldID GetFieldID(JNIEnv *env, jclass clazz, const
在java中我有: package com.mypkg.utils; ... public class attitude_calculator { private long native_pt
我已经为此苦苦挣扎了很长一段时间,现在已经束手无策了。基本上,我在我们的 Android 应用程序中包含了一个具有 native 组件的库。 在其中一个本地类的 init 方法中,init 包含以下内
看来我对 JNI 的运气并不好。我正在等待我买的书到货,但现在是试错法。 我正在使用 JNI 来实现 Lua 求值器。 evaluatorNew() 只是创建一个新的 Evaluator() 对象,创
我想使用 dlib 库进行人脸检测,但它不适用于旧手机。 我因以下堆栈跟踪而崩溃: E/AndroidRuntime( 4288): FATAL EXCEPTION: pool-1-thread-1
我是一名优秀的程序员,十分优秀!