引言
前面几篇文章基本上将 jni-rs 介绍完了。然而,还有一个较为重要的部分没说明,也就是动态注册。毕竟是可以投入生产的东西了,动态注册这么重要的东西怎么能少?C/C++有的东西,我Rust也得有!那么,开撸!
开发环境
操作系统:Windows 11
编码软件:Visual Studio Code 1.93.1 | Android Studio Ladybug | 2024.2.1 Beta 1
正文
本文将对 ndk 在 rust 中的动态注册进行介绍,并且将重点说明这过程中 所有权 转移的情况。
创建Rust项目
老样子,我们正常创建一个 example_5
的lib项目,然后改造它。
接着,打开 lib.rs
开始编码。
和C/C++一样 jni-rs 也提供了 JNI_OnLoad
函数,接受两个参数。
然后,我们按照常规写法,将 jvm
存起来(第14行)。
这里使用的是Rust提供的 OnceLock
它支持多线程安全,并且只允许赋值一次,读取多次。
读取方式在第20行。
最后,返回 JNI_VERSION_1_6
(值得注意的是,当返回 JNI_VERSION_1_8
时app会崩溃)。
动态注册
当准备工作完毕后,就可以实现上面的 //todo
了。
以下,就是动态注册的实现。
上图,第一个红色框我们将 env 改为了可变的变量,然后增加了第二个红框中的代码。
在第三个红色框中,使用NativeMehtod
结构体来表示它是一个本地方法,而它的第三个值fn_ptr
需要是一个C函数
的指针表示,所以这里的 native_method
函数被强转为了C指针
。
我们打开它的实现,可以看到它也有相关说明,第二个值类型就决定了该动态注册的方法是否为 静态的
,当类型为 JClass
时就表示该方法是静态方法
,当类型为 JObject
时就表示该方法为实例方法。
OK,Rust层到这儿就结束了。
编译出so文件后,我们就可以创建Android项目进行测试了。
cargo ndk -t armeabi-v7a -t arm64-v8a -o ./jniLibs build --release
创建Android项目
然后跑一下,看一下效果。
所有权导致崩溃
果然,前面顺风顺水(前面的几篇文章只要是通过了Rust的编译检查,在Android这边基本上是直接跑起来的),现在呢,总算是遭到报应了。
那么,就需要重新打包,并导出符号表查看崩溃情况了。
直接运行一下 cargo ndk
发现它提供了一个命令行参数 --no-strip
。
修改一下编译so的命令。
cargo ndk --no-strip -t armeabi-v7a -t arm64-v8a -o ./jniLibs build --release
重新编译覆盖进android项目后,再来查看崩溃情况。
诶,出现了。从截图看在报错列表中,只有 native_method
这个方法是我们自己写的,那么原因就是它咯。
可这个就是一个简单创建字符串的方法呀,正当我百思不得其解时,问了问AI。
这才恍然大悟,原来是 借用 出现了问题。
被动态注册的
native_method
实际上是直接与jvm进行交互的,所以jvm传入的env实参应该是所有权的转移而并不是可变or不可变的引用 ,因此当我使用env: &mut JNIEnv<'l>
时会照成app的崩溃。所以这里应该直接让native_method
的env
形参拿到所有权,也就是说将其修改为env: JNIEnv<'l>
或mut env: JNIEnv<'l>
才对。
而对于 register_jni_natives
函数而言,它是直接在rust代码层就被直接调用(本身就是作为一个封装函数)那么自然就允许借用了。
好,我们按照gpt的提示,修改一下 native_method
的env形参。
再次编译,复制,替换,运行(记得clean)。
结果展示
本篇完~
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/22378,转载请注明出处。
评论0