Rust移动开发:Rust在Android端集成使用介绍
Andorid调用Rust
-
目前Rust在移动端上的应用,一般作为应用sdk的提供,供各端使用,目前飞书底层使用Rust编写通用组件。
-
该篇适合对Android、Rust了解,想看如何做整合,如果想要工程源码,可以评论或留言有解疑也可进行询问(更多最新文章也可关注微信公号:良技漫谈)
一,开发环境:
-
确保rust开发环境,推荐官方文档, 安装即可
-
Android相关开发环境,需要NDK的下载安装
-
环境变量的配置,为命令行使用提供全局环境
开发工具:
- 1. 如果对android studio比较熟悉,可安装rust插件
-
安装完毕,对Rust Toolchain 位置进行配置确认,否则可能对rs文件无法识别,就无法愉快使用studio编写rust
2. 推荐使用VSCode编写rust代码,可以去下载 Visual Studio Code,然后安装rust相关插件即可。
二,创建Android工程:
-
• 如果对Android比较熟悉,使用studio来创建工程,和其他Android工程创建一样,创建Empty Activity,工程名 AndroidIntegratingRust
-
先编译通过该空工程,确保依赖资源下载完整。
三,添加rust lib库:
-
进入到刚创建的AndroidIntegratingRust工程下
1.使用rust Cargo创建 lib库:
Cargo new rust_lib --lib
-
• 创建成功后会有rust_lib库,结构如下:
├── app
│ ├── build
│ ├── build.gradle
│ ├── libs
│ ├── proguard-rules.pro
│ └── src
├── build
│ └── kotlin
├── build.gradle
├── gradle
│ └── wrapper
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
├── rust_lib //位置在这
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── src
│ └── target
└── settings.gradle
2.编辑Cargo.toml
-
输入目前需要的jni库依赖, https://crates.io/地址下确认版本, create-type 填写cdylib 动态链接库
[lib]
name = "rust_lib"
crate-type = ["cdylib"][dependencies]
jni = "0.20.0"
3.配置要编译so的linker及target
-
这个在rust_lib下创建.cargo目录,添加config.toml配置文件
-
填入linker对应的ndk地址:
[target.aarch64-linux-android]
linker = "/Users/android-sdk-macosx/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang++"[target.armv7-linux-androideabi]
linker = "/Users/android-sdk-macosx/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/armv7a-linux-androideabi21-clang++"
ps: 这是我的mac上ndk所在位置,参考Android官方ndk文档。
-
准备编译rust代码为so的环境已经准备完
四,编写Android和Rust代码:
-
创建Android代码, RustGreetings类, 使用kotlin所以用external声明JNI函数
class RustGreetings {fun sayHello(to: String): String {return greeting(to)}companion object {@JvmStatic external fun greeting(pattern: String): String}
}
-
在Rust lib库下,编写对应的JNI函数映射,从create.io下可以看到有关JNI的使用,代码如下
use jni::JNIEnv;// These objects are what you should use as arguments to your native
// function. They carry extra lifetime information to prevent them escaping
// this context and getting used after being GC'd.
use jni::objects::{JClass, JString};// This is just a pointer. We'll be returning it from our function. We
// can't return one of the objects with lifetime information because the
// lifetime checker won't let us.
use jni::sys::jstring;// This keeps Rust from "mangling" the name and making it unique for this
// crate.
#[no_mangle]
pub extern "system" fn Java_com_android_integratingrust_RustGreetings_greeting(env: JNIEnv,// This is the class that owns our static method. It's not going to be used,// but still must be present to match the expected signature of a static// native method.class: JClass,input: JString,
) -> jstring {// First, we have to get the string out of Java. Check out the `strings`// module for more info on how this works.let mut input: String = env.get_string(input).expect("Couldn't get java string!").into();input = append_string(&input);// Then we have to create a new Java string to return. Again, more info// in the `strings` module.let output = env.new_string(format!("Hello, {}!", input)).expect("Couldn't create java string!");// Finally, extract the raw pointer to return.output.into_raw()
}//============== rust code ===============
fn append_string(value: &str) -> String {let mut origin = String::from(value);origin.push_str("this is Rust");return origin;
}
五,编译Rust代码为so
-
编译之前确认之前rust环境是可以使用的了,且要看下rustup target 下是否已经有要交叉编译的工具了。
-
rustc --print target-list | grep android 可以查看相关android 交叉编译工具,(我们demo之前在配置target时,使用了32和64位的ARM CPU 架构linker)
aarch64-linux-android
arm-linux-androideabi
armv7-linux-androideabi
i686-linux-android
thumbv7neon-linux-androideabi
x86_64-linux-android
-
如果没有安装,需要安装下对应的
rustup target add aarch64-linux-android armv7-linux-androideabi
-
rustup show 可以看到当前rust开发语言环境,包括 (installed targets for active toolchain)
-
rustup target list可以查看到那些已经安装和rust支持的。
执行编译
-
到rust_lib目录下执行编译
cargo build --target aarch64-linux-android --release
-
编译成功到target目录下release下去查看对应的so文件
.
├── CACHEDIR.TAG
├── aarch64-linux-android
│ ├── CACHEDIR.TAG
│ └── release
├── armv7-linux-androideabi
│ ├── CACHEDIR.TAG
│ └── release
├── debug
│ ├── build
│ ├── deps
│ ├── examples
│ └── incremental
└── release├── build├── deps├── examples└── incremental
六,使用rust代码运行工程
sourceSets {main {jniLibs.srcDirs = ['src/main/libs']}}
-
copy 对应的so文件到 Android工程下src/main/libs下
-
在Android工程下build.gradle下记得引用so为jniLibs
PS: 也欢迎大家评论和交流~ 更多文章也可关注微信公号:良技漫谈
相关文章:

Rust移动开发:Rust在Android端集成使用介绍
Andorid调用Rust 目前Rust在移动端上的应用,一般作为应用sdk的提供,供各端使用,目前飞书底层使用Rust编写通用组件。 该篇适合对Android、Rust了解,想看如何做整合,如果想要工程源码,可以评论或留言有解疑…...

vue3动态监听div高度案例
案例场景 场景描述:现在左边的线条长度需要根据右边盒子的高度进行动态变化 实践代码案例 HTML部分 <div v-for"(device, index) in devices" :key"index"><!-- 动态设置 .left-bar 的高度 --><div class"left-bar"…...

数据转换 | Matlab基于SP符号递归图(Symbolic recurrence plots)一维数据转二维图像方法
目录 基本介绍程序设计参考资料获取方式 基本介绍 Matlab基于SP符号递归图(Symbolic recurrence plots)一维数据转二维图像方法 符号递归图(Symbolic recurrence plots)是一种一维时间序列转图像的技术,可用于平稳和非平稳数据集;对噪声具有…...

分类算法——逻辑回归 详解
逻辑回归(Logistic Regression)是一种广泛使用的分类算法,特别适用于二分类问题。尽管名字中有“回归”二字,逻辑回归实际上是一种分类方法。下面将从底层原理、数学模型、优化方法以及源代码层面详细解析逻辑回归。 1. 基本原理 …...

只允许指定ip远程连接ssh
我们都会使用securtcrt或者xshell等软件进行远程登录,这样虽然会给我们带来很多便捷,但是同样会存在一定的风险。有很多人专门通过重复的扫描试图破解我们的linux服务器,从而获取免费的“肉鸡”。因此我们可以通过设置hosts.allow和hosts.den…...

Rust 力扣 - 2841. 几乎唯一子数组的最大和
文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们遍历长度为k的窗口,用一个哈希表记录窗口内的所有元素(用来对窗口内元素去重),我们取哈希表中元素数量大于等于m的窗口总和的最大值 题解代码 use std::coll…...

TwinCL: A Twin Graph Contrastive Learning Model for Collaborative Filtering
TwinCL: A Twin Graph Contrastive Learning Model for Collaborative Filtering 摘要 在推荐和协同过滤领域,图对比学习(Graph Contrasive Learning,GCL)已经成为一种有影响的方法。然而,对比学习有效性的原因还没有…...

如何区分实例化网格中的每个实例
1)如何区分实例化网格中的每个实例 2)项目在模拟器上切换程序后有概率画面冻结 3)Unity工程导入团结引擎,GUID会变化,导致引用关系丢失 4)Mask在Android平台下渲染异常 这是第407篇UWA技术知识分享的推送&a…...

理解 WordPress | 第一篇:与内容管理系统的关系
初步了解 WordPress 在互联网世界里,WordPress 是一个家喻户晓的名字。它是一个开源的内容管理系统(Content Management System,简称 CMS),帮助用户轻松创建和管理网站。WordPress 诞生于 2003 年,最初是一…...

Python游戏脚本之实现飞机大战(附源码)
一.游戏设定 游戏界面如下图所示: 游戏的基本设定: 敌方共有大中小3款飞机,分为高中低三种速度; 子弹的射程并非全屏,而大概是屏幕长度的80%; 消灭小飞机需要1发子弹,中飞机需要8发,大飞机需要20发子弹; 每消灭一架小飞机得1000分,中飞机6000分,大飞…...

使用Spring Boot搭建简单的web服务
1 引言 1.1 Spring Boot简介 Spring Boot是由Pivotal团队提供的一套开源框架,旨在简化Spring应用的创建及部署。 一、核心设计思想 Spring Boot的核心设计思想是“约定优于配置”(Convention Over Configuration,简称COC)。这…...

【IF-MMIN】利用模态不变性特征进行缺失模态的鲁棒多模态情感识别
代码地址:github地址传送 文章是基于MMIN的改进 -> MMIN传送 abstract 多模态情感识别利用跨模态的互补信息来获得性能。然而,我们不能保证所有模式的数据总是存在于实践中。在跨模态数据缺失预测研究中,异质性模态之间的固有差异即模态…...

RGB图像,排列方式NHWC适合CPU计算,NCHW适合GPU计算
之前写过笔记OpenCV读取图像时按照BGR的顺序HWC排列,PyTorch按照RGB的顺序CHW排列,HWC格式排列,那么内存位置计算公式是? 在比较NHWC(channels_last)和NCHW(channels_first)这两种图像数据通道格式的效率时…...

布朗运动
内容来源 数理金融初步(原书第3版)Sheldon M. Ross著 冉启康译 机械工业出版社 布朗运动 定义 如果随机变量集合 X ( t ) X(t) X(t) 满足以下条件 X ( 0 ) X(0) X(0) 是一个给定的常数 对所有正数 y y y 和 t t t,随机变量 X ( y t …...

WPF+MVVM案例实战(二十二)- 制作一个侧边弹窗栏(CD类)
文章目录 1、案例效果1、侧边栏分类2、CD类侧边弹窗实现1、样式代码实现2、功能代码实现3 运行效果4、源代码获取1、案例效果 1、侧边栏分类 A类 :左侧弹出侧边栏B类 :右侧弹出侧边栏C类 :顶部弹出侧边栏D类 :底部弹出侧边栏2、CD类侧边弹窗实现 1、样式代码实现 在原有的…...

集成旺店通旗舰版售后单至MySQL数据库
旺店通旗舰版-售后单集成到MySQL的技术实现 在数据驱动的业务环境中,如何高效、准确地将旺店通旗舰奇门的数据集成到MySQL数据库,是许多企业面临的重要挑战。本文将分享一个具体的系统对接案例:旺店通旗舰版-售后单-->BI泰海-售后订单表(…...

【Linux】从零开始使用多路转接IO --- epoll
当你偶尔发现语言变得无力时, 不妨安静下来, 让沉默替你发声。 --- 里则林 --- 从零开始认识多路转接 1 epoll的作用和定位2 epoll 的接口3 epoll工作原理4 实现epollserverV1 1 epoll的作用和定位 之前提过的多路转接方案select和poll 都有致命缺点…...

爬虫学习4
from threading import Thread#创建任务 def func(name):for i in range(100):print(name,i)if __name__ __main__:#创建线程t1 Thread(targetfunc,args("1"))t2 Thread(targetfunc, args("2"))t1.start()t2.start()print("我是诛仙剑")from …...

CTF之web题集详情随手笔记
《Web安全》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484238&idx1&snca66551c31e37b8d726f151265fc9211&chksmc0e47a12f793f3049fefde6e9ebe9ec4e2c7626b8594511bd314783719c216bd9929962a71e6&scene21#wechat_redirect 1 WEB 1 靶场目…...

TDengine 集群能力:超越 InfluxDB 的水平扩展与开源优势
随着物联网、车联网等领域的快速发展,企业所面临的数据采集量呈爆炸式增长,这对 IT 基础设施和数据库提出了严峻挑战。传统单机版数据库逐渐无法应对高并发的数据写入和复杂的查询需求。因此,底层数据库必须具备水平扩展能力,以确…...

MATCH_DIRECT_BOOT_AWARE和MATCH_DIRECT_BOOT_UNAWARE
PackageManager.MATCH_DIRECT_BOOT_AWARE和PackageManager.MATCH_DIRECT_BOOT_UNAWARE 在Android系统中,PackageManager类提供了一些标志位,用于控制查询系统中的应用和组件时的行为。其中,MATCH_DIRECT_BOOT_AWARE和MATCH_DIRECT_BOOT_UNAWA…...

LabVIEW离心泵性能优化测试系统
开发了一套基于LabVIEW平台开发的离心泵性能优化测试系统。系统集成了数据采集、流量控制、数据存储、报表生成等功能,提供了低成本、便捷操作的解决方案,适用于工业场景中对离心泵性能的精确测评。 项目背景 随着工业化进程的加速,离心泵在…...

token和jwt区别
Token 和 JSON Web Token (JWT) 都是用于身份验证和授权的技术,但它们之间有一些重要的区别。下面是它们的主要区别和各自的特性: 1. 概念上的区别 Token: 广义概念:Token 是一个通用术语,指的是任何形式的令牌,用于在客户端和服务器之间传递身份验证和授权信息。实现方…...

新闻稿件管理:SpringBoot框架实战指南
3系统分析 3.1可行性分析 通过对本新闻稿件管理系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本新闻稿件管理系统采用SSM框架,JAVA作为开发语…...

AI运动小程序开发常见问题集锦二
截止到现在写博文时,我们的AI运动识别小程序插件已经迭代了23个版本,成功应用于健身、体育、体测、AR互动等场景;为了让正在集成或者计划进行功能扩展优化的用户,少走弯路、投入更少的开发资源,针对近期的咨询问题&…...

nginx安装
下载地址 https://nginx.org/en/download.html选择 把下载好的压缩包放在 解压 tar -zxf nginx-1.27.2.tar.gz下载 yum install -y gcc-c pcre pcre-devel zlib zlib-devel openssl openssl-devel ./configuremake&&make install这样表示安装成功 接下去启动nginx…...

【Linux驱动开发】内核定时器的配置和使用
【Linux驱动开发】内核定时器的配置和使用 文章目录 Linux内核时钟定时器调用方式延时函数 应用附录:嵌入式Linux驱动开发基本步骤开发环境驱动文件编译驱动安装驱动自动创建设备节点文件 驱动开发驱动设备号地址映射,虚拟内存和硬件内存地址字符驱动旧…...

Kubernetes架构及核心组件
一、基本架构 Kubernetes集群可以被看作是一个工厂,而各个组件则是这个工厂里的不同部门: Kubernetes API服务器:就像是这个工厂的总经理,负责接收所有的请求并将它们分配给相应的部门进行处理。 etcd:就像是这个工厂的记事本,负责记录所有的配置信息和状态信息,以便其…...

Fastflow工作流系统源码
可视化工作流程审批插件,作为一款高效的企业管理工具,其核心价值在于帮助用户根据企业独特的业务模式和管理模式,灵活自定义所需的各种流程应用。这一功能极大地提升了企业的自主性和灵活性,使得企业能够迅速构建出贴合自身运营需…...

小林渗透入门:burpsuite+proxifier抓取小程序流量
目录 前提: 代理: proxifier: 步骤: bp证书安装 bp设置代理端口: proxifier设置规则: proxifier应用规则: 结果: 前提: 在介绍这两个工具具体实现方法之前࿰…...