Android JNI 进阶(含完整 Demo),字节跳动Android岗面试题

  • 参数一:jintArray:java 传递过来的数组
  • 参数二:修改后的数组
  • 参数三:修改的模式,填 0 就好

ReleaseStringChars解释:

ReleaseStringChars是用来释放 JNI 内存的,虽然说不释放也可以,因为在方法结束的时候会弹栈,一旦弹栈就会自动释放内存,但是如果说一个方法中有 5000 行代码,在一直不释放,等待到 JNI 弹栈自动释放,那么就会引起 JNI 在调用该方法的时候占用空间略大(养成好习惯)

运行结果:

native 运行结果:
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 参数一为42
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 参数二为24.420000
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 参数三为1
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 参数四为李元霸
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 参数五为成龙
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 参数五为李小龙
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 参数五为松井宝
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 参数五为迪丽热巴
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 参数五为ohh
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 第六个参数为:101
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 第六个参数为:104
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 第六个参数为:102
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 第六个参数为:162
2021-04-28 17:36:22.217 6501-6501/com.example.jni E/szj: 第六个参数为:161

java 运行结果:
2021-04-28 17:36:22.217 6501-6501/com.example.jni I/szjjava 层打印: 101
2021-04-28 17:36:22.217 6501-6501/com.example.jni I/szjjava 层打印: 104
2021-04-28 17:36:22.217 6501-6501/com.example.jni I/szjjava 层打印: 102
2021-04-28 17:36:22.217 6501-6501/com.example.jni I/szjjava 层打印: 162
2021-04-28 17:36:22.217 6501-6501/com.example.jni I/szjjava 层打印: 161

引用类型 静态/动态 方法调用

java 代码:

public native void nativeMethod(Persion persion);

辅助图:
在这里插入图片描述
右侧的红框是需要调用的方法;

  • void setName()
  • void setAge()
  • static void show(String name)

native 代码:

extern “C”
JNIEXPORT void JNICALL
Java_com_example_jni_activity_AdvancedActivity_nativeMethod(JNIEnv *env, jobject thiz,
jobject persion) {

/**

  • 获取 Persion 的 class
  • 源码: jclass FindClass(const char* name)
    */
    jclass j_class = env->FindClass(“com/example/jni/bean/Persion”);

/**

  • 获取方法 ID:
  • jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)
    */
    jmethodID j_method_id = env->GetMethodID(j_class, “getName”, “()Ljava/lang/String;”);

//获取 Persion getName方法返回值
jstring j_strName = static_cast(env->CallObjectMethod(persion, j_method_id));

//修改为 C++认识的 char*类型
char *j_char_name = const_cast<char *>(env->GetStringUTFChars(j_strName, NULL));
LOGE(“通过 getName获取值为:%s”, j_char_name)

//获取 setName的 ID
jmethodID j_setName_id = env->GetMethodID(j_class, “setName”, “(Ljava/lang/String;)V”);
//获取静态的 show 方法
jmethodID j_show_id = env->GetStaticMethodID(j_class, “show”, “(Ljava/lang/String;)V”);

env->CallVoidMethod(persion, j_setName_id, env->NewStringUTF(“糖果超甜”));
env->CallStaticVoidMethod(j_class, j_show_id, env->NewStringUTF(“糖果超甜”));
}

这个方法中没有陌生方法,大家应该都认识,看不懂记得评论区留言哦~

运行结果为:

native运行结果:
2021-04-28 17:44:29.775 6501-6501/com.example.jni E/szj: 通过 getName获取值为:洪静宝

java 运行结果:
2021-04-28 17:44:29.775 6501-6501/com.example.jni I/szjjava 层 setName方法:: 糖果超甜
2021-04-28 17:44:29.775 6501-6501/com.example.jni I/szjjava 层show方法:: 糖果超甜

引用类型进阶

java 定义native方法:

public native void nativeMethod2(Dog dog);

辅助图:
在这里插入图片描述

native 层代码:

extern “C”
JNIEXPORT void JNICALL
Java_com_example_jni_activity_AdvancedActivity_nativeMethod2(JNIEnv *env, jobject thiz,
jobject dog_jobj) {

//获取 Dog 类的 Class
jclass j_dog_class = env->GetObjectClass(dog_jobj);

//获取 Dog 类中的 DogShow 方法 ID
jmethodID jmethodId = env->GetMethodID(j_dog_class, “DogShow”,
“(Lcom/example/jni/bean/Persion;)V”);

//获取 Persion 的 jclass
jclass j_persion_class = env->FindClass(“com/example/jni/bean/Persion”);
//获取 Persion 的 jobj //AllocObject只实例化对象,不会调用构造函数
jobject j_persion_job = env->AllocObject(j_persion_class);

//给 Persion 赋值
jmethodID j_setName_id = env->GetMethodID(j_persion_class, “setName”, “(Ljava/lang/String;)V”);
jmethodID j_setAge_id = env->GetMethodID(j_persion_class, “setAge”, “(I)V”);

//调用 Persion 的 setName 和 setAge 给 name 和 age 赋值
env->CallVoidMethod(j_persion_job, j_setName_id, env->NewStringUTF(“蔡徐坤”));
env->CallVoidMethod(j_persion_job, j_setAge_id, 52);

//调用 Dog 的 DogShow(Persion)方法
env->CallVoidMethod(dog_jobj, jmethodId, j_persion_job);

//释放引用类型 class 和 job 都建议释放
env->DeleteLocalRef(j_dog_class);
env->DeleteLocalRef(j_persion_class);
env->DeleteLocalRef(j_persion_job);
}

思路:

  • 创建 Persion 对象
  • 调用 Persion 的 setName() / setAge() 方法给 name/age 赋值
  • 创建 Dog 对象
  • 调用 Dog 对象中的 DogShow(Persion) 方法,把 Persion 传递进去即可

AllocObject解释:

AllocObject 只实例化对象,不会调用构造函数,在新创建对象(不是传递过来的)的时候,必须用这个来实例化对象,否则调用 实例化的对象不起作用

构造函数调用

java 定义 native 方法:

public native void nativeStructure(Dog dog);

native 代码:

extern “C”
JNIEXPORT void JNICALL
Java_com_example_jni_activity_AdvancedActivity_nativeStructure(JNIEnv *env, jobject thiz,
jobject dog) {

//获取 Dog 的 jclass
jclass j_dog_class = env->GetObjectClass(dog);

//获取构造方法
jmethodID id1 = env->GetMethodID(j_dog_class, “”, “()V”);
jmethodID id2 = env->GetMethodID(j_dog_class, “”, “(II)V”);
jmethodID id3 = env->GetMethodID(j_dog_class, “”, “(III)V”);

//调用构造方法
env->CallVoidMethod(dog, id1);
env->CallVoidMethod(dog, id2, 100, 200);
env->CallVoidMethod(dog, id3, 300, 400, 500);
}

这里非常好理解:

构造方法用表示即可,其余的都没变

全局引用

java 定义 native 代码:

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

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

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

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

如何成为Android高级架构师!

架构师必须具备抽象思维和分析的能力,这是你进行系统分析和系统分解的基本素质。只有具备这样的能力,架构师才能看清系统的整体,掌控全局,这也是架构师大局观的形成基础。 你如何具备这种能力呢?一是来自于经验,二是来自于学习。

架构师不仅要具备在问题领域上的经验,也需要具备在软件工程领域内的经验。也就是说,架构师必须能够准确得理解需求,然后用软件工程的思想,把需求转化和分解成可用计算机语言实现的程度。经验的积累是需要一个时间过程的,这个过程谁也帮不了你,是需要你去经历的。

但是,如果你有意识地去培养,不断吸取前人的经验的话,还是可以缩短这个周期的。这也是我整理架构师进阶此系列的始动力之一。


成为Android架构师必备知识技能

对应导图的学习笔记(由阿里P8大牛手写,我负责整理成PDF笔记)

部分内容展示

《设计思想解读开源框架》

  • 目录
  • 热修复设计
  • 插件化框架设计

    《360°全方面性能优化》
  • 设计思想与代码质量优化
  • 程序性能优化

2838750)]

  • 插件化框架设计
    [外链图片转存中…(img-5gdufgQi-1711132838750)]
    《360°全方面性能优化》
    [外链图片转存中…(img-JvA96nQi-1711132838751)]
  • 设计思想与代码质量优化
    [外链图片转存中…(img-udCr8rfs-1711132838751)]
  • 程序性能优化
    [外链图片转存中…(img-D8n0Lnj9-1711132838751)]

本文在开源项目:【GitHub 】中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

  • 27
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值