第一类问题:
问题现象:
E/dalvikvm( 3349): ERROR: couldn't find native method
E/dalvikvm( 3349): Requested: Lcom/orbbec/NativeNI/OrbbecUtils;.CoventDepthTORGB:(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;II)I
W/dalvikvm( 3349): Exception Ljava/lang/NoSuchMethodError; thrown while initializing Lcom/orbbec/NativeNI/OrbbecUtils;
W/dalvikvm( 3349): threadid=13: thread exiting with uncaught exception (group=0x4157c300)
E/AndroidRuntime( 3349): FATAL EXCEPTION: Thread-314
E/AndroidRuntime( 3349): Process: com.orbbec.obcolor, PID: 3349
E/AndroidRuntime( 3349): java.lang.NoSuchMethodError: no static or non-static method "Lcom/orbbec/NativeNI/OrbbecUtils;.CoventDepthTORGB(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;II)I"
E/AndroidRuntime( 3349): at java.lang.Runtime.nativeLoad(Native Method)
E/AndroidRuntime( 3349): at java.lang.Runtime.doLoad(Runtime.java:421)
E/AndroidRuntime( 3349): at java.lang.Runtime.loadLibrary(Runtime.java:362)
E/AndroidRuntime( 3349): at java.lang.System.loadLibrary(System.java:526)
E/AndroidRuntime( 3349): at com.orbbec.NativeNI.OrbbecUtils.
E/AndroidRuntime( 3349): at com.orbbec.stream.AndroidCamera.getRGBData(AndroidCamera.java:224)
E/AndroidRuntime( 3349): at orbbec.com.obcolor.MainActivity$4.run(MainActivity.java:317)
W/ActivityManager( 469): Force finishing activity com.orbbec.obcolor/orbbec.com.obcolor.MainActivity
提示找不到CoventDepthTORGB这个本地方法。
首先在网上找到这个问题的最常见的方法是:
在Android.mk中增加行:LOCAL_PROGUARD_ENABLED := disabled
发生问题时的注册表:
JNINativeMethod jniMethods[] = {
{ "CoventDepthTORGB", "(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;II)I", (void*)&Native_CoventDepthTORGB},
{ "DrawDepth", "([III)I", (void*)&Native_DrawDepth},
{ "ByteToRGBData", "([B[IIII)I", (void*)&Native_ByteToRGBData},
{ "ByteToBGRData", "([B[IIII)I", (void*)&Native_ByteToBGRData},
{ "NV21ToRGBA", "([BLjava/nio/ByteBuffer;II)I", (void*)&Native_NV21ToRGBA},
{ "NV21ToBGR", "([B[III)I", (void*)&Native_NV21ToBGR},
{ "NV21ToMirrorRGBA", "([B[III)I", (void*)&Native_NV21ToMirrorRGBA},
{ "YUV422ToRGBA", "([B[IIIZ)I", (void*)&Native_YUV422ToRGBA},
{ "UserOffset", "(Ljava/lang/String;Ljava/nio/ByteBuffer;[SII[FI)I", (void*)&Native_UserOffset},
{ "DepthOffset", "([S[SIII)I", (void*)&Native_DepthOffset},
{ "GetOffsetValue", "(Ljava/lang/String;F)F", (void*)&GetOffsetValue},
{ "BgrToArgb", "([I[III)I", (void*)&Native_BgrToArgb},
{"IsPro", "()Z", (void*)&Native_IsPro},
{"ByteToRGBA", "(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;III)I", (void*)&Native_ByteToRGBA},
};
发生问题时的java层本地方法的声明:
public class OrbbecUtils {
static {
System.loadLibrary("OrbbecUtils");
System.loadLibrary("OrbbecUtils_jni");
}
public native static int CoventFromDepthTORGB(int[] pdepth,int width, int height );
public native static int ByteToRGBData(byte[] pByteColor,int[] pIntColor, int width, int height ,int sdkVersion);
public native static int NV21ToMirrorRGBA(byte[] nv21data,int[] rgbdata, int width, int height );
public native static int NV21ToRGBA(byte[] nv21data,int[] rgbdata, int width, int height );
public native static int YUV422ToRGBA(byte[] yuvdata,int[] rgbdata, int width, int height, boolean mirror);
public native static boolean IsPro();
public native static int DepthOffset(short []src, short []dst, int w, int h, int offset);
public native static float GetOffsetValue(String serialnumber, float distances);
public native static int NV21ToBGR(byte[] nv21Byte,int[] bgrData, int width, int height );
public native static int BgrToArgb(int [] bgr, int []rgb, int w, int h);
public native static int Exit();
}
结果发现在本地方法声明时,没有声明CoventDepthTORGB,所以在注册本地方法与其实现之间的对应关系时,将CoventDepthTORGB去掉即可。
JNINativeMethod jniMethods[] = {
// { "CoventDepthTORGB", "(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;II)I", (void*)&Native_CoventDepthTORGB},
{ "DrawDepth", "([III)I", (void*)&Native_DrawDepth},
{ "ByteToRGBData", "([B[IIII)I", (void*)&Native_ByteToRGBData},
{ "ByteToBGRData", "([B[IIII)I", (void*)&Native_ByteToBGRData},
{ "NV21ToRGBA", "([BLjava/nio/ByteBuffer;II)I", (void*)&Native_NV21ToRGBA},
{ "NV21ToBGR", "([B[III)I", (void*)&Native_NV21ToBGR},
{ "NV21ToMirrorRGBA", "([B[III)I", (void*)&Native_NV21ToMirrorRGBA},
{ "YUV422ToRGBA", "([B[IIIZ)I", (void*)&Native_YUV422ToRGBA},
{ "UserOffset", "(Ljava/lang/String;Ljava/nio/ByteBuffer;[SII[FI)I", (void*)&Native_UserOffset},
{ "DepthOffset", "([S[SIII)I", (void*)&Native_DepthOffset},
{ "GetOffsetValue", "(Ljava/lang/String;F)F", (void*)&GetOffsetValue},
{ "BgrToArgb", "([I[III)I", (void*)&Native_BgrToArgb},
{"IsPro", "()Z", (void*)&Native_IsPro},
{"ByteToRGBA", "(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;III)I", (void*)&Native_ByteToRGBA},
};
第二类问题:前面不符合,方法声明的签名为:public native static int NV21ToRGBA(byte[] nv21data,int[] rgbdata, int width, int height );
注册时指定的签名为: { "NV21ToRGBA", "([BLjava/nio/ByteBuffer;II)I", (void*)&Native_NV21ToRGBA},
D/OrbbecUtils( 3613): pid: 0xffffffff
D/dalvikvm( 3613): Added shared lib /data/app-lib/com.orbbec.obcolor-1/libOrbbecUtils_jni.so 0x41842a00
E/dalvikvm( 3613): ERROR: couldn't find native method
E/dalvikvm( 3613): Requested: Lcom/orbbec/NativeNI/OrbbecUtils;.NV21ToRGBA:([BLjava/nio/ByteBuffer;II)I
E/dalvikvm( 3613): Candidate: Lcom/orbbec/NativeNI/OrbbecUtils;.NV21ToRGBA:([B[III)I
W/dalvikvm( 3613): Exception Ljava/lang/NoSuchMethodError; thrown while initializing Lcom/orbbec/NativeNI/OrbbecUtils;
W/dalvikvm( 3613): threadid=14: thread exiting with uncaught exception (group=0x4157c300)
E/AndroidRuntime( 3613): FATAL EXCEPTION: Thread-327
E/AndroidRuntime( 3613): Process: com.orbbec.obcolor, PID: 3613
E/AndroidRuntime( 3613): java.lang.NoSuchMethodError: no static or non-static method "Lcom/orbbec/NativeNI/OrbbecUtils;.NV21ToRGBA([BLjava/nio/ByteBuffer;II)I"
E/AndroidRuntime( 3613): at java.lang.Runtime.nativeLoad(Native Method)
E/AndroidRuntime( 3613): at java.lang.Runtime.doLoad(Runtime.java:421)
E/AndroidRuntime( 3613): at java.lang.Runtime.loadLibrary(Runtime.java:362)
E/AndroidRuntime( 3613): at java.lang.System.loadLibrary(System.java:526)
E/AndroidRuntime( 3613): at com.orbbec.NativeNI.OrbbecUtils.
E/AndroidRuntime( 3613): at com.orbbec.stream.AndroidCamera.getRGBData(AndroidCamera.java:224)
E/AndroidRuntime( 3613): at orbbec.com.obcolor.MainActivity$4.run(MainActivity.java:317)
修正方法为让签名保持一直即可。
关于签名不一致的另外一个例子:
{"getJointPos", "(ILcom/orbbec/global/SkeletonJoint;Lcom/orbbec/global/Point3D;)I", (void*)jni_getJointPos}, 由于Lcom/orbbec/global/SkeletonJoint;Lcom/orbbec/global/Point3D;这两个类型的包名,路径不正确导致。
3,JNI_OnLoad实现中,找不到申明本地方法的类导致。
#define REGISTER_CLASS "com/orbbec/interaction/NativeMethods"
jclass clz = env->FindClass(REGISTER_CLASS);
由于REGISTER_CLASS指定的类的路径不对,导致找不到本地方法。