//获取instance的类名称
jclass cls = (*env)->GetObjectClass(env,instance);
if(cls==NULL)
{
LOGD(“Class %s not found”);
}

//获取方法ID,第二个参数为类名称,第三个参数为方法名称,第三个参数为方法签名,详细参见签名对照表
jmethodID id =(*env)->GetMethodID(env,cls,“show”,“(Ljava/lang/String;)V”);
if(id !=NULL)
{
//访问方法,第二个为类实例,第三个参数为方法ID,第四和第四以后为方法参数,
// 根据返回类型不同,调用不同的CallXXXMethod方法,xxx返回类型
(*env)->CallVoidMethod(env,instance,id,s);
}
}

2.4、jni访问java中的静态方法

java代码

public static void showStatic(String s){
Log.i(“MainActivity”,“show static:”+s);
}
public native void showStaticString(String s);

jni代码

//访问Java中的showStatic静态方法
JNIEXPORT void JNICALL Java_com_zzy_ndkdemo_MainActivity_showStaticString(JNIEnv *env, jobject instance, jstring s) {

//获取instance的类名称
jclass cls = (*env)->GetObjectClass(env,instance);
if(cls==NULL)
{
LOGD(“Class %s not found”);
}

//获取静态方法ID,第二个参数为类名称,第三个参数为方法名称,第三个参数为方法签名,详细参见签名对照表
jmethodID id =(*env)->GetStaticMethodID(env,cls,“showStatic”,“(Ljava/lang/String;)V”);
if(id !=NULL)
{
//访问方法,第二个为类名称,第三个参数为方法ID,第四和第四以后为方法参数,
// 根据返回类型不同,调用不同的CallStaticXXXMethod方法,xxx返回类型
(*env)->CallStaticVoidMethod(env,cls,id,s);
}
}

1、从中我们可以看出静态方法比非静态方法的访问多加了一个static,访问函数由类实例,变成类引用。

2、如果静态方法不存在instance类中,我们可以通过FindClass进行访问,其中第二个参数为类的全路径

jclass cls = (*env)->FindClass(env, “com/zzy/ndkdemo/JniDemo”);
if (cls == NULL) {
LOGD(“Class %s not found”);
}

2.5、jni访问java中的字段

java代码

User user = new User();
user.name = “zhang san”;
user.age = 30;
User.token = “2018-2011—3223”;

String name = showUserName(user);
Log.i(“MainActivity”,“show name:”+name);
public native String showUserName(User user);

jni代码

//访问User中的字段name
JNIEXPORT jstring JNICALL Java_com_zzy_ndkdemo_MainActivity_showUserName(JNIEnv *env, jobject instance, jobject user) {

//获取User的类名称
jclass cls=(*env)->GetObjectClass(env,user);
if (cls == NULL) {
LOGD(“Class %s not found”);
return NULL;
}

//获取字段ID,第二个参数类名称,第三个参数字段名,第三个参数字段签名,详细参见签名对照表
jfieldID id = (*env)->GetFieldID(env,cls,“name”,“Ljava/lang/String;”);
if(id==NULL)
{
LOGD(“Field token not found”);
return NULL;
}
//获取字段内容,调用GetXXXField,xxx为字段类型。除基本类型外,其他的都使用GetObjectField
jstring name=(jstring) (*env)->GetObjectField(env,user,id);
return name;
}

2.6、jni访问Java中的静态字段

java代码

User user = new User();
user.name = “zhang san”;
user.age = 30;
User.token = “2018-2011—3223”;
String token =showUserStaticToken(user);
Log.i(“MainActivity”,“show static token:”+token);
public native String showUserStaticToken(User user);

jni代码

//访问User中的静态字段Token
JNIEXPORT jstring JNICALL Java_com_zzy_ndkdemo_MainActivity_showUserStaticToken(JNIEnv *env, jobject instance, jobject user) {

//获取User的类名称
jclass cls=(*env)->GetObjectClass(env,user);
if (cls == NULL) {
LOGD(“Class %s not found”);
return NULL;
}

//获取静态字段ID,第二个参数类名称,第三个参数字段名,第三个参数字段签名,详细参见签名对照表
jfieldID id = (*env)->GetStaticFieldID(env,cls,“token”,“Ljava/lang/String;”);
if(id==NULL)
{
LOGD(“Field token not found”);
return NULL;
}

//获取字段内容,调用GetStaticXXXField,xxx为字段类型。除基本类型外,其他的都使用GetStaticObjectField
jstring token=(*env)->GetStaticObjectField(env,cls,id);
return token;
}

1、从中我们可以看出静态字段比非静态字段的访问多加了一个static,访问函数由类实例,变成类引用。

2、如果静态字段中不存在instance类中,我们可以通过FindClass进行访问,其中第二个参数为类的全路径

jclass cls = (*env)->FindClass(env, “com/zzy/ndkdemo/User”);
if (cls == NULL) {
LOGD(“Class %s not found”);
}

2.7、jni中更新java的字段内容

java代码

User user = updateUser(user);
Log.i(“MainActivity”,“updateUser name:”+user.name+" age:“+user.age+” token:"+User.token);
public native User updateUser(User user);

jni代码

//更新user内容
JNIEXPORT jobject JNICALL Java_com_zzy_ndkdemo_MainActivity_updateUser(JNIEnv *env, jobject instance,jobject user)
{
//获取User的类名称
jclass cls=(*env)->GetObjectClass(env,user);
if (cls == NULL) {
LOGD(“Class %s not found”);
return NULL;
}

//获取每一个字段ID,第二个参数类名称,第三个参数字段名,第三个参数字段签名,详细参见签名对照表
jfieldID idName = (*env)->GetFieldID(env,cls,“name”,“Ljava/lang/String;”);
jfieldID idAge = (*env)->GetFieldID(env,cls,“age”,“I”);
jfieldID idToken = (*env)->GetStaticFieldID(env,cls,“token”,“Ljava/lang/String;”);

//将cha字符串转成jstring
jstring name = (*env)->NewStringUTF(env, “李四”);
jstring token = (*env)->NewStringUTF(env, “new token”);

//更新字段内容,调用setxxxField,xxx为字段类型,如果是静态字段还需要加上static
//第二个参数为需要修改的类实例或则类名,第三个参数为字段Id,第四个参数为需要修改的内容
(*env)->SetObjectField(env,user,idName,name);
(*env)->SetIntField(env,user,idAge,20);
(*env)->SetStaticObjectField(env,cls,idToken,token);

return user;
}

2.8、jni中创建java类实例

java代码

User user = createUser();
Log.i(“MainActivity”,“createUser name:”+user.name+" age:“+user.age+” token:"+User.token);
public native User createUser();

jni代码

//创建user实例
JNIEXPORT jobject JNICALL Java_com_zzy_ndkdemo_MainActivity_createUser(JNIEnv *env, jobject instance)
{
//在指定路径查找到USer类名称
jclass cls = (*env)->FindClass(env, “com/zzy/ndkdemo/User”);
if (cls == NULL) {
LOGD(“Class %s not found”);
}

//获取User类的构造方法ID,第二个参数为类名称,第三个参数固定为""
//第四个参数为构造函数签名,详细参见签名对照表
jmethodID id= (*env)->GetMethodID(env, cls, “”, “()V”);

//实例化User类,第二个参数类名称,第三个参数构造方法ID
jobject user = (*env)->NewObject(env, cls, id);
if (user == NULL) {
LOGD(“Create User failed”);
}

//获取每一个字段ID,第二个参数类名称,第三个参数字段名,第三个参数字段签名,详细参见签名对照表
jfieldID idName = (*env)->GetFieldID(env,cls,“name”,“Ljava/lang/String;”);
jfieldID idAge = (*env)->GetFieldID(env,cls,“age”,“I”);
jfieldID idToken = (*env)->GetStaticFieldID(env,cls,“token”,“Ljava/lang/String;”);

//将cha字符串转成jstring
jstring name = (*env)->NewStringUTF(env, “王五”);
jstring token = (*env)->NewStringUTF(env, “second token”);

先自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以扫码领取!

img

最后总结

搞定算法,面试字节再不怕,有需要文章中分享的这些二叉树、链表、字符串、栈和队列等等各大面试高频知识点及解析

最后再分享一份终极手撕架构的大礼包(学习笔记):分布式+微服务+开源框架+性能优化

image

e5c14a7895254671a72faed303032d36.jpg" alt=“img” style=“zoom: 33%;” />

最后总结

搞定算法,面试字节再不怕,有需要文章中分享的这些二叉树、链表、字符串、栈和队列等等各大面试高频知识点及解析

最后再分享一份终极手撕架构的大礼包(学习笔记):分布式+微服务+开源框架+性能优化

[外链图片转存中…(img-byB9Lhl7-1711392778062)]

需要更多Java资料的小伙伴可以帮忙点赞+关注,点击传送门,即可免费领取!

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐