惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
V
V2EX
博客园 - 【当耐特】
Vercel News
Vercel News
雷峰网
雷峰网
爱范儿
爱范儿
WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Microsoft Azure Blog
Microsoft Azure Blog
F
Full Disclosure
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog
NISL@THU
NISL@THU
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Attack and Defense Labs
Attack and Defense Labs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC
P
Proofpoint News Feed
B
Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
K
Kaspersky official blog
I
InfoQ
Google Online Security Blog
Google Online Security Blog
L
LINUX DO - 最新话题
Project Zero
Project Zero
Engineering at Meta
Engineering at Meta
V
Visual Studio Blog
AI
AI
Schneier on Security
Schneier on Security
B
Blog RSS Feed
T
Tor Project blog
H
Help Net Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LINUX DO - 热门话题
阮一峰的网络日志
阮一峰的网络日志
S
Security @ Cisco Blogs
T
Threat Research - Cisco Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
C
Cyber Attacks, Cyber Crime and Cyber Security
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
V2EX - 技术
V2EX - 技术
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
A
Arctic Wolf
Webroot Blog
Webroot Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main

LengYue's Blog

在 Android 中实现 iOS 液态玻璃效果(二:折射与渗透效果) | LengYue's Blog 在 Android 中实现 iOS 液态玻璃效果 | LengYue's Blog Dart 单线程模型的本质 | LengYue's Blog 使用 Rust 开发 Android 底层库,并简化 Java 与 Rust 相互操作 | LengYue's Blog 使用 GoMobile 创建 Android、iOS 跨平台 WebSocket Library | LengYue's Blog Flutter error not found dart html | LengYue's Blog AndroidStudio新版本Logcat | LengYue's Blog Typecho to Hugo | LengYue's Blog GetX Router 设置返回值 | LengYue's Blog Flutter 基础 | Dart 语法 mixin | LengYue's Blog 不使用第三方软件实现Obsidian多平台实时同步 | LengYue's Blog Android 使用字节码 hook 修复第三发 bug | LengYue's Blog 在 Jetpack Compose 中使用输入框(TextField )遇到的一些问题 | LengYue's Blog Android-使用@AutoService实现spi | LengYue's Blog RecyclerView使用优化的ListAdapter | LengYue's Blog ⾃定义布局流程 | LengYue's Blog ViewModel之自定义构造函数 | LengYue's Blog Android Jetpack Compose 超快速上手指南 | LengYue's Blog android 11 [api 30] 适配指南 | LengYue's Blog Android 声明式 UI 框架 Litho 初探 —— Sections API | LengYue's Blog Android 声明式 UI 框架 Litho 初探 —— Layout | LengYue's Blog Android声明式UI框架 Litho 初探 —— MountSpec的使用 | LengYue's Blog Android声明式UI框架 Litho 初探——基础使用 | LengYue's Blog Android声明式UI框架 Litho 初探 ——两种数据类型 | LengYue's Blog
将 Rust 编译为可在 Android 上使用的二进制文件 | LengYue's Blog
LengYue · 2023-03-20 · via LengYue's Blog

Rust 语言已经成为了越来越受欢迎的一种系统级编程语言。它被广泛使用来开发高性能的系统软件,模块化的库,以及并发和并行计算应用程序。不仅如此,它还可以为其他平台和设备生成二进制代码,包括 Android 操作系统。如果你也想在 Android 上利用 Rust 开发应用程序

创建 Rust 项目

首先创建 Rust 项目

为了跟前文 (使用 GoMobile 创建 Android、iOS 跨平台 WebSocket Library) 呼应,我们这里也使用 Rust 借助 tokio 写一个 WebSocket Server。 main.rs

use async_trait::async_trait;
use ezsockets::Error;
use ezsockets::Server;
use ezsockets::Socket;
use std::net::SocketAddr;
type SessionID = u16;
type Session = ezsockets::Session<SessionID, ()>;
struct EchoServer {}
#[async_trait]
impl ezsockets::ServerExt for EchoServer {
   type Session = EchoSession;
   type Call = ();
   async fn on_connect(
       &mut self,
       socket: Socket,
       address: SocketAddr,
       _args: (),
   ) -> Result<Session, Error> {
       let id = address.port();
       let session = Session::create(|handle| EchoSession { id, handle }, id, socket);
       Ok(session)
   }
   async fn on_disconnect(
       &mut self,
       _id: <Self::Session as ezsockets::SessionExt>::ID,
   ) -> Result<(), Error> {
       Ok(())
   }
   async fn on_call(&mut self, call: Self::Call) -> Result<(), Error> {
       let () = call;
       Ok(())
   }
}
struct EchoSession {
   handle: Session,
   id: SessionID,
}
#[async_trait]
impl ezsockets::SessionExt for EchoSession {
   type ID = SessionID;
   type Args = ();
   type Call = ();
   fn id(&self) -> &Self::ID {
       &self.id
   }
   async fn on_text(&mut self, text: String) -> Result<(), Error> {
       self.handle.text(text);
       Ok(())
   }
   async fn on_binary(&mut self, _bytes: Vec<u8>) -> Result<(), Error> {
       unimplemented!()
   }
   async fn on_call(&mut self, call: Self::Call) -> Result<(), Error> {
       let () = call;
       Ok(())
   }
}
#[tokio::main]
async fn main() {
   tracing_subscriber::fmt::init();
   let (server, _) = Server::create(|_server| EchoServer {});
   ezsockets::tungstenite::run(server, "127.0.0.1:9091", |_| async move { Ok(()) })
       .await
       .unwrap();
}

dependencies:

[dependencies]
async-trait = "0.1.67"
ezsockets = "0.5.1"
tokio = { version = "1.26.0", features = ["full"] }
tracing = "0.1.37"
tracing-subscriber = "0.3.16"

添加 targets

> rustup target add aarch64-linux-android \
                  armv7-linux-androideabi \
                  i686-linux-android \
                  x86_64-linux-android

指定 linker

Rust 默认调用平台安装的 cc 编译器,所哟我们需要指定 Android 的 CC 和 AR 首先安装 Android NDK

部分教程说需要执行下面的命令:

python ${NDK_HOME}/build/tools/make_standalone_toolchain.py --api 26 > --arch arm64 --install-dir NDK/arm64

其实是不用的。在新的 NDK 中已经自自带了。我们在项目跟目录创建 .cargo/config

[target.aarch64-linux-android]
linker = '/home/ying/Android/Sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang'
ar = '/home/ying/Android/Sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar'

编译 Rust 代码

执行:

 cargo build --target aarch64-linux-android --release

会在 target/aarch64-linux-android/release 目录下生成产物

如果你使用 r23c 及以上版本,那么 cargo build 可能会出现以下错误,原因是 libgcc.a 已经被 libunwind.a 替代:

ld: error: unable to find library -lgcc

可以把把 libunwind.a 复制一份重命名为 libgcc.a,它的路径为:/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/

在 Android 中运行

可以参考上篇文章 使用 GoMobile 创建 Android、iOS 跨平台 WebSocket Library 稍微修改即可:

....
    MainScope().launch(Dispatchers.IO) {
        Runtime.getRuntime().exec("so 的路径")
    }
...

总结

要在 Android 设备运行 Rust 可执行我呢间需要:

  • 使用 rustup 添加 android 设备相关的 target
  • 项目中配置 linker ar
  • 编译 rust 代码
  • android 项目中执行 rust 文件