1.自定义Java方法
// java方法
public class MyJavaClass {
public String getName(String content) {
return "hello world -> " + content;
}
}
2.编译该类获取.class 文件
javac MyJavaClass.java
3.获取该类的签名
javap -p -s 包名.MyJavaClass
// 获取结果如下
警告: 二进制文件MyJavaClass包含com.barray.hellojni.MyJavaClass
Compiled from "MyJavaClass.java"
public class com.barray.hellojni.MyJavaClass {
public com.barray.hellojni.MyJavaClass();
descriptor: ()V
public java.lang.String getName(java.lang.String);
descriptor: (Ljava/lang/String;)Ljava/lang/String;
}
4.Java调用C++方法
public native void demoMethod(MyJavaClass myJavaClass);
5.C代码调用
extern "C"
JNIEXPORT void JNICALL
Java_com_barray_hellojni_MainActivity_demoMethod(JNIEnv *env, jobject thiz, jobject my_java_class) {
// 获取当前对象的类文件
jclass jc = env->GetObjectClass(my_java_class);
// 获取当前需要调用的方法id
jmethodID methodId = env->GetMethodID(jc,"getName","(Ljava/lang/String;)Ljava/lang/String;");
// 调用该方法
char * content = "from C++";
jstring j_content = env->NewStringUTF(content);
jstring j_result = (jstring)env->CallObjectMethod(my_java_class,methodId,j_content);
const char * c_result = env->GetStringUTFChars(j_result,JNI_FALSE);
__android_log_print(ANDROID_LOG_INFO,"JNI_TAG","result ---> %s",c_result);
}
Android原生Java方法
以getPackageName方法为例
1.找到android.jar这个包
2.将.jar改为.zip文件
3.获取该类的签名(同上)
javap -p -s ContextWrapper
// 获取以下信息
...
public java.lang.String getPackageName();
descriptor: ()Ljava/lang/String;
...
java签名分析
| Java类型 | 符号标识 |
|---|---|
| boolean | Z |
| byte | B |
| char | C |
| short | S |
| int | I |
| long | J |
| float | F |
| double | D |
| void | V |
| 对象 | 以L开头;结尾,中间用/隔开包名及类名 |



