關鍵字: JNI, GetMethodID, java.lang.NoSuchMethodError, javap, 內(nèi)部類
20180816 tjy
轉(zhuǎn)載請注明出處
這幾天維護一個app, 需要把一些事情放到so文件中去實現(xiàn)。
在寫jni調(diào)用java方法的時候,遇到方法的signature錯誤導致GetMethodID調(diào)用拋出java.lang.NoSuchMethodError錯誤,在解決這個問題上面花了一些時間。
最后各種百度,發(fā)現(xiàn)javap能很好的解決這個問題。
javap -s的解釋如下,即打印signature. 這個 signature正是寫JNI函數(shù)需要的。
-s Print internal type signatures
john@john-ThinkPad-Edge-E435:~/workspace/temp$ javap --help
Usage: javap <options> <classes>
where possible options include:
-help --help -? Print this usage message
-version Version information
-v -verbose Print additional information
-l Print line number and local variable tables
-public Show only public classes and members
-protected Show protected/public classes and members
-package Show package/protected/public classes
and members (default)
-p -private Show all classes and members
-c Disassemble the code
-s Print internal type signatures
-sysinfo Show system info (path, size, date, MD5 hash)
of class being processed
-constants Show static final constants
-classpath <path> Specify where to find user class files
-bootclasspath <path> Override location of bootstrap class files
具體JNI的使用方法就不在這里展開了,直接上代碼和運行結(jié)果,希望能給遇到類似問題的人一個思路。
package com.test;
class Test {
private int mX;
private InternalClass mIc;
public void setX(int x) {
mX = x;
}
public int getX() {
return mX;
}
public void setIc(InternalClass ic) {
mIc = ic;
}
public InternalClass getIc() {
return mIc;
}
//internal class
public class InternalClass {
private String mStr;
public String toString() {
return mStr;
}
}
//main
public static void main() {
Test test = new Test();
}
}
編譯之后得到如下的結(jié)果:
john@john-ThinkPad-Edge-E435:~/workspace/temp$ javac Test.java
john@john-ThinkPad-Edge-E435:~/workspace/temp$
john@john-ThinkPad-Edge-E435:~/workspace/temp$ ls
Test.class Test$InternalClass.class Test.java Test.java~
javap -s的運行結(jié)果如下:
其中有一個setIc函數(shù)的參數(shù)是個內(nèi)部類??梢钥聪聝?nèi)部類的寫法。
john@john-ThinkPad-Edge-E435:~/workspace/temp$ javap -s Test.class
Compiled from "Test.java"
class com.test.Test {
com.test.Test();
Signature: ()V
public void setX(int);
Signature: (I)V
public int getX();
Signature: ()I
public void setIc(com.test.Test$InternalClass);
Signature: (Lcom/test/Test$InternalClass;)V
public com.test.Test$InternalClass getIc();
Signature: ()Lcom/test/Test$InternalClass;
public static void main();
Signature: ()V
}
john@john-ThinkPad-Edge-E435:~/workspace/temp$
在看內(nèi)部類的javap -s的結(jié)果:
john@john-ThinkPad-Edge-E435:~/workspace/temp$ javap -s Test\$InternalClass.class
Compiled from "Test.java"
public class com.test.Test$InternalClass {
final com.test.Test this$0;
Signature: Lcom/test/Test;
public com.test.Test$InternalClass(com.test.Test);
Signature: (Lcom/test/Test;)V
public java.lang.String toString();
Signature: ()Ljava/lang/String;
}
john@john-ThinkPad-Edge-E435:~/workspace/temp$