<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Native on zed的博客</title><link>https://www.dust-zed.site/android/native/</link><description>Recent content in Native on zed的博客</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sun, 11 Jan 2026 13:59:24 +0800</lastBuildDate><atom:link href="https://www.dust-zed.site/android/native/index.xml" rel="self" type="application/rss+xml"/><item><title>UniFFI 实战手册：Android + Rust 混合开发</title><link>https://www.dust-zed.site/android/uniffi-practical-guide-android-rust/</link><pubDate>Sun, 11 Jan 2026 13:59:24 +0800</pubDate><guid>https://www.dust-zed.site/android/uniffi-practical-guide-android-rust/</guid><description>&lt;p>UniFFI 的核心价值是减少手写 JNI 胶水代码：Rust 侧定义类型和函数，UniFFI 生成 Kotlin 绑定，让 Android 侧像调用普通 Kotlin API 一样访问 Rust Core。&lt;/p>
&lt;h2 id="核心结论">核心结论
&lt;/h2>&lt;ol>
&lt;li>UniFFI 适合把 Rust Core 暴露给 Kotlin/Swift 等上层语言。&lt;/li>
&lt;li>Android 场景下通常生成 Kotlin binding，再加载 Rust &lt;code>.so&lt;/code>。&lt;/li>
&lt;li>类型边界要保持简单，避免跨 FFI 传递复杂平台对象。&lt;/li>
&lt;li>异步、回调、错误类型要提前设计，否则后期迁移成本很高。&lt;/li>
&lt;li>推荐优先使用过程宏模式，减少 &lt;code>.udl&lt;/code> 文件和实现之间的漂移。&lt;/li>
&lt;/ol>
&lt;h2 id="一环境与配置">一、环境与配置
&lt;/h2>&lt;h3 id="11-cargotoml-依赖配置">1.1 &lt;code>Cargo.toml&lt;/code> 依赖配置
&lt;/h3>&lt;p>在 Rust 项目根目录的 &lt;code>Cargo.toml&lt;/code> 中，注意 &lt;code>crate-type&lt;/code> 和 &lt;code>uniffi&lt;/code> 的版本一致性：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">lib&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># &amp;#34;cdylib&amp;#34; 是必须的，用于生成 Android 可用的 .so 文件&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">crate-type&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;cdylib&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">name&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;rust_lib_core&amp;#34;&lt;/span> &lt;span class="c"># 通用库名&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># features = [&amp;#34;tokio&amp;#34;] 开启异步支持，这对高性能 App 至关重要&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">uniffi&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">version&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;0.28&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">features&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;tokio&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">thiserror&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;1.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 用于驱动异步运行时&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">tokio&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">version&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">features&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;full&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 常用库推荐&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">log&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;0.4&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">android_logger&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;0.13&amp;#34;&lt;/span> &lt;span class="c"># 让 Rust 日志输出到 Logcat&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">build-dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># ⚠️ 警告：这里的版本必须和 dependencies 里的版本严格一致！&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">uniffi&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">version&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;0.28&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">features&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;build&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="12-rust-入口文件-librs">1.2 Rust 入口文件 (&lt;code>lib.rs&lt;/code>)
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// 这一行宏会自动生成 JNI 胶水代码，不可省略
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">uniffi&lt;/span>::&lt;span class="fm">setup_scaffolding!&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c1">// 初始化日志系统（建议放在某个 init 函数中调用）
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="cp">#[uniffi::export]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">fn&lt;/span> &lt;span class="nf">init_logger&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">android_logger&lt;/span>::&lt;span class="n">init_once&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">android_logger&lt;/span>::&lt;span class="n">Config&lt;/span>::&lt;span class="n">default&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="n">with_min_level&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">log&lt;/span>::&lt;span class="n">Level&lt;/span>::&lt;span class="n">Debug&lt;/span>&lt;span class="p">),&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="13-uniffitoml-配置文件">1.3 &lt;code>uniffi.toml&lt;/code> 配置文件
&lt;/h3>&lt;p>在项目根目录（与&lt;code>Cargo.toml&lt;/code>同级）创建&lt;code>uniffi.toml&lt;/code>：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">bindings&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">kotlin&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 生成的 Kotlin 代码的包名，必须与 Android 项目结构匹配&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">package_name&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;com.example.app.core&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 编译生成的 .so 文件名 (去掉 lib 前缀)。例如 librust_lib_core.so -&amp;gt; rust_lib_core&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">cdylib_name&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;rust_lib_core&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="14-gradle-集成android-侧">1.4 Gradle 集成（Android 侧）
&lt;/h3>&lt;p>在 Android 项目的 &lt;code>app/build.gradle.kts&lt;/code> 中，你需要让 Gradle 自动调用 &lt;code>uniffi-bindgen&lt;/code>。 &lt;em>(注：市面上有 &lt;code>net.navatwo.uniffi&lt;/code> 等插件，但手动配置更稳定)&lt;/em>&lt;/p>
&lt;p>关键步骤逻辑：&lt;/p>
&lt;ol>
&lt;li>Cargo 编译 Rust -&amp;gt; 生成 &lt;code>.so&lt;/code>&lt;/li>
&lt;li>&lt;code>uniffi-bindgen&lt;/code> 读取 &lt;code>.so&lt;/code> -&amp;gt; 生成 &lt;code>.kt&lt;/code>&lt;/li>
&lt;li>将 &lt;code>.kt&lt;/code> 加入 Android 源码集&lt;/li>
&lt;/ol>
&lt;h2 id="二类型系统通信的词汇">二、类型系统：通信的词汇
&lt;/h2>&lt;h4 id="21-基础类型映射表">2.1 基础类型映射表
&lt;/h4>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Rust&lt;/th>
&lt;th>Kotlin&lt;/th>
&lt;th>说明&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>u8&lt;/code> / &lt;code>i8&lt;/code>&lt;/td>
&lt;td>&lt;code>UByte&lt;/code> / &lt;code>Byte&lt;/code>&lt;/td>
&lt;td>-&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>i32&lt;/code>&lt;/td>
&lt;td>&lt;code>Int&lt;/code>&lt;/td>
&lt;td>-&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>u64&lt;/code>&lt;/td>
&lt;td>&lt;code>ULong&lt;/code>&lt;/td>
&lt;td>&lt;strong>坑点&lt;/strong>：Kotlin 的 Unsigned 类型使用起来较繁琐，有时建议在 Rust 层转为 &lt;code>i64&lt;/code> (Long) 传输时间戳。&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>f32&lt;/code> / &lt;code>f64&lt;/code>&lt;/td>
&lt;td>&lt;code>Float&lt;/code> / &lt;code>Double&lt;/code>&lt;/td>
&lt;td>-&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>bool&lt;/code>&lt;/td>
&lt;td>&lt;code>Boolean&lt;/code>&lt;/td>
&lt;td>-&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>String&lt;/code>&lt;/td>
&lt;td>&lt;code>String&lt;/code>&lt;/td>
&lt;td>自动处理 UTF-8 转换，内存安全。&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>Vec&amp;lt;u8&amp;gt;&lt;/code>&lt;/td>
&lt;td>&lt;code>ByteArray&lt;/code>&lt;/td>
&lt;td>&lt;strong>重点&lt;/strong>：二进制流、文件数据、protobuf。&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>Vec&amp;lt;T&amp;gt;&lt;/code>&lt;/td>
&lt;td>&lt;code>List&amp;lt;T&amp;gt;&lt;/code>&lt;/td>
&lt;td>列表，会有拷贝开销。&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>Option&amp;lt;T&amp;gt;&lt;/code>&lt;/td>
&lt;td>&lt;code>T?&lt;/code>&lt;/td>
&lt;td>完美映射为 Kotlin 的可空类型。&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>HashMap&amp;lt;K, V&amp;gt;&lt;/code>&lt;/td>
&lt;td>&lt;code>Map&amp;lt;K, V&amp;gt;&lt;/code>&lt;/td>
&lt;td>映射为 Kotlin Map。&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h4 id="22-record--纯数据包dto">2.2 Record &amp;ndash; 纯数据包（DTO）
&lt;/h4>&lt;ul>
&lt;li>性质：值拷贝。在传输时进行序列化/反序列化。&lt;/li>
&lt;li>用途：配置对象，一次性状态快照。&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#[derive(uniffi::Record)]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">strcut&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">AppConfig&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">api_endpoint&lt;/span>: &lt;span class="nb">String&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">timeout_ms&lt;/span>: &lt;span class="kt">u32&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">max_retries&lt;/span>: &lt;span class="kt">u8&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="23-enum--状态与事件">2.3 Enum &amp;ndash; 状态与事件
&lt;/h4>&lt;ul>
&lt;li>性质：根据是否携带数据，生成不同的Kotlin结构&lt;/li>
&lt;li>用途：状态机、业务事件、错误码。&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#[derive(uniffi::Enum)]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">enum&lt;/span> &lt;span class="nc">NetworkState&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Disconnected&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Connecting&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Connected&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">session_id&lt;/span>: &lt;span class="nb">String&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">ping_ms&lt;/span>: &lt;span class="kt">u32&lt;/span> &lt;span class="p">},&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Failed&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">String&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="24-object对象-核心服务">2.4 Object（对象）&amp;ndash; 核心服务
&lt;/h4>&lt;ul>
&lt;li>性质：引用传递。传递的是&lt;code>Handle(u64)&lt;/code>&lt;/li>
&lt;li>生命周期: 有&lt;code>Arc&lt;/code>智能指针管理。&lt;/li>
&lt;li>线程安全：必须实现&lt;code>Sync + Send&lt;/code>。这意味着内部状态通常需要&lt;code>Mutex&lt;/code>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="k">use&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>::&lt;span class="n">sync&lt;/span>::&lt;span class="n">Mutex&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="cp">#[derive(uniffi::Object)]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">struct&lt;/span> &lt;span class="nc">CoreService&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">inner&lt;/span>: &lt;span class="nc">Mutex&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">ServiceState&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="cp">#[uniffi::export]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">imple&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">CoreService&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="cp">#[uniffi::constructor]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">fn&lt;/span> &lt;span class="nf">new&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>-&amp;gt; &lt;span class="nc">Self&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="bp">Self&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">inner&lt;/span>&lt;span class="w"> &lt;/span>: &lt;span class="nc">Mutex&lt;/span>::&lt;span class="n">new&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ServiceState&lt;/span>::&lt;span class="n">default&lt;/span>&lt;span class="p">())&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="三函数与交互">三、函数与交互
&lt;/h2>&lt;h4 id="31-异步函数async--彻底告别卡顿">3.1 异步函数(Async) &amp;ndash; 彻底告别卡顿
&lt;/h4>&lt;p>原理： Rust &lt;code>Future&lt;/code>通过UniFFI的polling机制桥接到Kotlin &lt;code>Coroutines&lt;/code>。&lt;/p>
&lt;p>Rust写法:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#[uniffi::export]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">impl&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">CoreService&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">async&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">fn&lt;/span> &lt;span class="nf">perform_action&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">param&lt;/span>: &lt;span class="nb">String&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>-&amp;gt; &lt;span class="nb">Result&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="nb">String&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">CoreError&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">tokio&lt;/span>::&lt;span class="n">time&lt;/span>::&lt;span class="n">sleep&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>::&lt;span class="n">time&lt;/span>::&lt;span class="n">Duration&lt;/span>::&lt;span class="n">from_secs&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)).&lt;/span>&lt;span class="k">await&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">param&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">is_empty&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">Err&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">CoreError&lt;/span>::&lt;span class="n">InvalidParam&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nb">Ok&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;success_result&amp;#34;&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">into&lt;/span>&lt;span class="p">())&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="32-回调接口--反向通知">3.2 回调接口 &amp;ndash; 反向通知
&lt;/h3>&lt;p>场景：Rust后台线程需要通知Android UI更新&lt;/p>
&lt;p>Rust定义&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#[uniffi::export(callback_interface)]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">trait&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">StateListener&lt;/span>: &lt;span class="nb">Send&lt;/span> &lt;span class="o">+&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">Sync&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">fn&lt;/span> &lt;span class="nf">on_progress&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">percent&lt;/span>: &lt;span class="kt">u32&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">fn&lt;/span> &lt;span class="nf">on_log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">msg&lt;/span>: &lt;span class="nb">String&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Kotlin实现&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-kotlin" data-lang="kotlin">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">AndroidListener&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">StateListener&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">override&lt;/span> &lt;span class="k">fun&lt;/span> &lt;span class="nf">onProgress&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">percent&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">UInt&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">MainScope&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="n">launch&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">progressBar&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">progress&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">percent&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">toInt&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">override&lt;/span> &lt;span class="k">fun&lt;/span> &lt;span class="nf">onLog&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">msg&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">String&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nc">Log&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">d&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;RustCore&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">msg&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="四高级技巧">四、高级技巧
&lt;/h2>&lt;h4 id="41-自定义类型--包装systemtime">4.1 自定义类型 &amp;ndash; 包装&lt;code>SystemTime&lt;/code>
&lt;/h4>&lt;p>场景：你想在接口里直接使用Rust的&lt;code>SystemTime&lt;/code>，但Uniffi不支持。你需要把它转换为&lt;code>u64&lt;/code>传给Kotlin。&lt;/p>
&lt;p>Rust实现：&lt;/p>
&lt;ol>
&lt;li>创建一个NewType 包装器（如果需要）或直接为你的类型实现 &lt;code>UniffiCustomTypeConverter&lt;/code>。&lt;/li>
&lt;li>此处演示简单包装模式（UniFFI 尚不支持直接对标准库类型实现 Converter，通常使用 NewType）。&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#[derive(uniffi::Object)]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">struct&lt;/span> &lt;span class="nc">RustTime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>::&lt;span class="n">time&lt;/span>::&lt;span class="n">SystemTime&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="cp">#[uniffi::export]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">impl&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">RustTime&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="cp">#[uniffi::constructor]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">fn&lt;/span> &lt;span class="nf">now&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>-&amp;gt; &lt;span class="nc">Self&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="bp">Self&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>::&lt;span class="n">time&lt;/span>::&lt;span class="n">SystemTime&lt;/span>::&lt;span class="n">now&lt;/span>&lt;span class="p">())&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c1">// 转为毫秒时间戳给 Kotlin 用
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">fn&lt;/span> &lt;span class="nf">to_millis&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>-&amp;gt; &lt;span class="kt">u64&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="mf">0.&lt;/span>&lt;span class="n">duration_since&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>::&lt;span class="n">time&lt;/span>::&lt;span class="no">UNIX_EPOCH&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">unwrap_or_default&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">as_millis&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">as&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">u64&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="42-错误处理">4.2 错误处理
&lt;/h4>&lt;p>让异常携带数据，实现精细化UI交互。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#[derive(Debug, thiserror::Error, uniffi::Error)]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">enum&lt;/span> &lt;span class="nc">ActionError&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="cp">#[error(&lt;/span>&lt;span class="s">&amp;#34;操作受限，冷却中: {retry_after}秒&amp;#34;&lt;/span>&lt;span class="cp">)]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Throttled&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">retry_after&lt;/span>: &lt;span class="kt">u32&lt;/span> &lt;span class="p">},&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="43-内存管理">4.3 内存管理
&lt;/h4>&lt;p>UniFFI的对象虽然有GC兜底，但在高性能场景下，必须&lt;strong>手动释放&lt;/strong>重资源对象。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-kotlin" data-lang="kotlin">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// 在 Android ViewModel 中
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">override&lt;/span> &lt;span class="k">fun&lt;/span> &lt;span class="nf">onCleared&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">super&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">onCleared&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">coreService&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">destory&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Clean Architecture + Rust：Kotlin UI 与 Rust Core 的边界</title><link>https://www.dust-zed.site/android/clean-architecture-rust-practice/</link><pubDate>Sun, 11 Jan 2026 13:02:10 +0800</pubDate><guid>https://www.dust-zed.site/android/clean-architecture-rust-practice/</guid><description>&lt;p>把 Rust 引入 Android 项目时，最重要的问题不是“能不能调用 Rust”，而是“哪些逻辑值得放到 Rust”。如果边界不清楚，跨语言调用只会增加复杂度。&lt;/p>
&lt;h2 id="核心结论">核心结论
&lt;/h2>&lt;ol>
&lt;li>Kotlin 适合处理 Android 平台能力、生命周期、权限、UI 和依赖注入。&lt;/li>
&lt;li>Rust 适合承载可跨平台复用、计算密集、协议解析或强一致性的核心逻辑。&lt;/li>
&lt;li>Domain 层应该定义稳定接口和模型，隔离 UI 与具体实现。&lt;/li>
&lt;li>FFI 边界要尽量窄，避免 Kotlin 和 Rust 互相泄漏内部细节。&lt;/li>
&lt;li>使用 Rust 的收益必须大于构建、调试、类型映射和团队学习成本。&lt;/li>
&lt;/ol>
&lt;h2 id="架构模型">架构模型
&lt;/h2>&lt;pre tabindex="0">&lt;code class="language-mermaid" data-lang="mermaid">graph LR
UI[&amp;#34;Kotlin UI / Compose&amp;#34;]
VM[&amp;#34;ViewModel&amp;#34;]
Domain[&amp;#34;Domain Interfaces / Models&amp;#34;]
Adapter[&amp;#34;Kotlin Adapter / UniFFI Binding&amp;#34;]
Rust[&amp;#34;Rust Core&amp;#34;]
UI --&amp;gt; VM
VM --&amp;gt; Domain
Domain --&amp;gt; Adapter
Adapter --&amp;gt; Rust
&lt;/code>&lt;/pre>&lt;p>职责划分：&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>层&lt;/th>
&lt;th>职责&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Kotlin UI&lt;/td>
&lt;td>渲染、交互、生命周期&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ViewModel&lt;/td>
&lt;td>UI 状态管理、调用 UseCase&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Domain&lt;/td>
&lt;td>接口、领域模型、用例边界&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Adapter&lt;/td>
&lt;td>Kotlin 与 Rust 类型适配&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Rust Core&lt;/td>
&lt;td>核心逻辑、协议、计算、跨平台能力&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="domain-作为契约">Domain 作为契约
&lt;/h2>&lt;p>Domain 层不应该关心底层是 Kotlin、Rust 还是 C++。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-kotlin" data-lang="kotlin">&lt;span class="line">&lt;span class="cl">&lt;span class="k">interface&lt;/span> &lt;span class="nc">GameRepository&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">suspend&lt;/span> &lt;span class="k">fun&lt;/span> &lt;span class="nf">getGameDetails&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">id&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">String&lt;/span>&lt;span class="p">):&lt;/span> &lt;span class="n">Game&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">suspend&lt;/span> &lt;span class="k">fun&lt;/span> &lt;span class="nf">startSession&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">config&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">SessionConfig&lt;/span>&lt;span class="p">):&lt;/span> &lt;span class="n">SessionResult&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>ViewModel 只依赖这个接口：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-kotlin" data-lang="kotlin">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">GameViewModel&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">private&lt;/span> &lt;span class="k">val&lt;/span> &lt;span class="py">repository&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">GameRepository&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">ViewModel&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Rust 只是接口的一种实现来源。&lt;/p>
&lt;h2 id="kotlin-侧边界">Kotlin 侧边界
&lt;/h2>&lt;p>Kotlin 保留这些职责：&lt;/p>
&lt;ol>
&lt;li>Compose / View UI；&lt;/li>
&lt;li>Android 生命周期；&lt;/li>
&lt;li>权限、通知、Intent 等平台能力；&lt;/li>
&lt;li>Hilt/Koin 依赖装配；&lt;/li>
&lt;li>UI 状态和一次性事件。&lt;/li>
&lt;/ol>
&lt;p>不要把 Android &lt;code>Context&lt;/code>、&lt;code>Activity&lt;/code>、&lt;code>View&lt;/code> 等平台对象传进 Rust Core。&lt;/p>
&lt;h2 id="rust-侧边界">Rust 侧边界
&lt;/h2>&lt;p>Rust 更适合：&lt;/p>
&lt;ol>
&lt;li>协议解析；&lt;/li>
&lt;li>编解码辅助逻辑；&lt;/li>
&lt;li>复杂业务规则；&lt;/li>
&lt;li>高并发网络核心；&lt;/li>
&lt;li>跨 Android/iOS/桌面复用的能力。&lt;/li>
&lt;/ol>
&lt;p>Rust 不适合直接处理：&lt;/p>
&lt;ol>
&lt;li>Android 生命周期；&lt;/li>
&lt;li>UI 状态；&lt;/li>
&lt;li>权限弹窗；&lt;/li>
&lt;li>依赖注入容器；&lt;/li>
&lt;li>和平台强绑定的对象。&lt;/li>
&lt;/ol>
&lt;h2 id="依赖装配">依赖装配
&lt;/h2>&lt;p>Hilt 负责把 Rust 实现装配成 Domain 接口：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-kotlin" data-lang="kotlin">&lt;span class="line">&lt;span class="cl">&lt;span class="nd">@Module&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nd">@InstallIn&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">SingletonComponent&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="k">class&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">object&lt;/span> &lt;span class="nc">DataModule&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nd">@Provides&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">fun&lt;/span> &lt;span class="nf">provideGameRepository&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">rustService&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">RustGameService&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">):&lt;/span> &lt;span class="n">GameRepository&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">RustGameRepository&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">rustService&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这样 UI 层不需要知道 Rust 细节。&lt;/p>
&lt;h2 id="回看清单">回看清单
&lt;/h2>&lt;ol>
&lt;li>Rust Core 应该服务架构边界，而不是制造新的耦合。&lt;/li>
&lt;li>Domain 层定义稳定协议，Kotlin/Rust 都围绕它实现。&lt;/li>
&lt;li>FFI 传输模型要简单、明确、可版本化。&lt;/li>
&lt;li>平台对象留在 Kotlin，核心逻辑放到 Rust。&lt;/li>
&lt;li>引入 Rust 前先问：这段逻辑是否真的需要跨平台或高性能核心。&lt;/li>
&lt;/ol></description></item><item><title>Rust JNI 环境配置：Android NDK、cargo-ndk 与 ABI</title><link>https://www.dust-zed.site/android/rust-jni-setup/</link><pubDate>Wed, 15 Oct 2025 13:45:38 +0800</pubDate><guid>https://www.dust-zed.site/android/rust-jni-setup/</guid><description>&lt;p>Android 调用 Rust 的第一步不是写 JNI，而是把交叉编译环境配稳定。这里重点整理 Rust target、NDK、cargo-ndk 和 ABI 的关系。&lt;/p>
&lt;h2 id="核心结论">核心结论
&lt;/h2>&lt;ol>
&lt;li>Android 上运行的是 &lt;code>.so&lt;/code> 动态库，不是普通桌面可执行文件。&lt;/li>
&lt;li>Rust 需要安装 Android 对应 target。&lt;/li>
&lt;li>NDK 提供 Android 平台的交叉编译工具链。&lt;/li>
&lt;li>&lt;code>cargo-ndk&lt;/code> 可以简化 ABI、platform、输出目录等配置。&lt;/li>
&lt;li>先验证能产出 &lt;code>.so&lt;/code>，再接 Kotlin/JNI。&lt;/li>
&lt;/ol>
&lt;h2 id="环境检查">环境检查
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rustc --version
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cargo --version
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>确认 Android SDK 和 NDK 已安装。通常可以在 Android Studio 里检查：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">Settings / Preferences
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -&amp;gt; Android SDK
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -&amp;gt; SDK Tools
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -&amp;gt; NDK
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="安装-rust-android-target">安装 Rust Android target
&lt;/h2>&lt;p>常见 target：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rustup target add aarch64-linux-android
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">rustup target add armv7-linux-androideabi
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">rustup target add x86_64-linux-android
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>对应关系：&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Android ABI&lt;/th>
&lt;th>Rust target&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>arm64-v8a&lt;/code>&lt;/td>
&lt;td>&lt;code>aarch64-linux-android&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>armeabi-v7a&lt;/code>&lt;/td>
&lt;td>&lt;code>armv7-linux-androideabi&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>x86_64&lt;/code>&lt;/td>
&lt;td>&lt;code>x86_64-linux-android&lt;/code>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>实际发布通常优先保证 &lt;code>arm64-v8a&lt;/code>。&lt;/p>
&lt;h2 id="安装-cargo-ndk">安装 cargo-ndk
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">cargo install cargo-ndk
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>验证：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">cargo ndk --version
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="配置-ndk-路径">配置 NDK 路径
&lt;/h2>&lt;p>常见环境变量：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">export&lt;/span> &lt;span class="nv">ANDROID_HOME&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/Library/Android/sdk&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">export&lt;/span> &lt;span class="nv">ANDROID_NDK_HOME&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$ANDROID_HOME&lt;/span>&lt;span class="s2">/ndk/&amp;lt;version&amp;gt;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>检查：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ls &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$ANDROID_NDK_HOME&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>应该能看到 &lt;code>toolchains&lt;/code>、&lt;code>platforms&lt;/code> 或相关 NDK 目录。&lt;/p>
&lt;h2 id="编译-rust-动态库">编译 Rust 动态库
&lt;/h2>&lt;p>&lt;code>Cargo.toml&lt;/code>：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">lib&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">crate-type&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;cdylib&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>编译：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">cargo ndk &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -t arm64-v8a &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -o ../android/app/src/main/jniLibs &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> build --release
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>输出结构通常是：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">app/src/main/jniLibs/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">└── arm64-v8a/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> └── librust_core.so
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="kotlin-侧加载">Kotlin 侧加载
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-kotlin" data-lang="kotlin">&lt;span class="line">&lt;span class="cl">&lt;span class="k">object&lt;/span> &lt;span class="nc">NativeBridge&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">init&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nc">System&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">loadLibrary&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;rust_core&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>注意：&lt;code>System.loadLibrary(&amp;quot;rust_core&amp;quot;)&lt;/code> 不写 &lt;code>lib&lt;/code> 前缀，也不写 &lt;code>.so&lt;/code> 后缀。&lt;/p>
&lt;h2 id="回看清单">回看清单
&lt;/h2>&lt;ol>
&lt;li>ABI、Rust target、&lt;code>.so&lt;/code> 输出目录必须对应。&lt;/li>
&lt;li>NDK 是交叉编译工具链，cargo-ndk 是简化工具。&lt;/li>
&lt;li>&lt;code>crate-type = [&amp;quot;cdylib&amp;quot;]&lt;/code> 是生成 Android &lt;code>.so&lt;/code> 的关键。&lt;/li>
&lt;li>Kotlin 加载库名时去掉 &lt;code>lib&lt;/code> 和 &lt;code>.so&lt;/code>。&lt;/li>
&lt;li>先跑通单 ABI，再扩展多 ABI 和 Gradle 自动化。&lt;/li>
&lt;/ol></description></item><item><title>Android Rust 混合开发入门：NDK、JNI、ABI 与 .so</title><link>https://www.dust-zed.site/android/android-rust-integration-intro/</link><pubDate>Wed, 15 Oct 2025 11:55:59 +0800</pubDate><guid>https://www.dust-zed.site/android/android-rust-integration-intro/</guid><description>&lt;p>Android 与 Rust 混合开发的核心链路是：Rust 编译成 Android 可加载的 &lt;code>.so&lt;/code>，Kotlin/Java 通过 JNI 或 UniFFI 访问其中的能力。&lt;/p>
&lt;h2 id="核心结论">核心结论
&lt;/h2>&lt;ol>
&lt;li>NDK 提供 Android Native 开发和交叉编译工具链。&lt;/li>
&lt;li>Rust 代码最终要编译成对应 ABI 的 &lt;code>.so&lt;/code>。&lt;/li>
&lt;li>JNI 是 JVM 与 Native 世界之间的桥。&lt;/li>
&lt;li>&lt;code>.so&lt;/code> 需要放到 &lt;code>jniLibs/&amp;lt;abi&amp;gt;/&lt;/code> 或由构建流程打进 APK/AAB。&lt;/li>
&lt;li>只有在跨平台复用、性能、协议/算法核心等场景下，引入 Rust 才更值得。&lt;/li>
&lt;/ol>
&lt;h2 id="什么是ndk">什么是NDK?
&lt;/h2>&lt;p>&lt;strong>NDK = Native Development Kit(原生开发工具包)&lt;/strong>&lt;/p>
&lt;p>&lt;strong>一句话解释&lt;/strong>&lt;/p>
&lt;p>NDK 是 Android 提供的工具集，让你能用 &lt;strong>C/C++/Rust&lt;/strong> 等原生语言开发 Android 应用的一部分。&lt;/p>
&lt;hr>
&lt;h2 id="android应用的两种开发方式">Android应用的两种开发方式
&lt;/h2>&lt;pre tabindex="0">&lt;code>┌─────────────────────────────────────────┐
│ Android 应用 │
├─────────────────────────────────────────┤
│ │
│ 方式 1: Java/Kotlin (Android SDK) │
│ ┌──────────────────────────────────┐ │
│ │ Kotlin/Java 代码 │ │
│ │ ↓ │ │
│ │ 编译为 DEX 字节码 │ │
│ │ ↓ │ │
│ │ 在 Dalvik/ART 虚拟机运行 │ │
│ └──────────────────────────────────┘ │
│ │
│ 方式 2: C/C++/Rust (Android NDK) │
│ ┌──────────────────────────────────┐ │
│ │ C/C++/Rust 代码 │ │
│ │ ↓ │ │
│ │ 编译为 .so 文件 (机器码) │ │
│ │ ↓ │ │
│ │ 直接在 CPU 上运行 (无虚拟机) │ │
│ └──────────────────────────────────┘ │
│ │
│ 两者通过 JNI 桥接 │
└─────────────────────────────────────────┘
&lt;/code>&lt;/pre>&lt;h2 id="为什么需要ndk">为什么需要NDK？
&lt;/h2>&lt;h3 id="对比理解">对比理解
&lt;/h3>&lt;p>纯 &lt;strong>Java/Kotlin(SDK):&lt;/strong>&lt;/p>
&lt;pre tabindex="0">&lt;code>优点:
✅ 开发简单
✅ 跨设备兼容好
✅ 调试方便
缺点:
❌ 性能有限 (虚拟机开销)
❌ 某些功能无法实现
❌ 无法复用 C/C++ 库
&lt;/code>&lt;/pre>&lt;p>&lt;strong>NDK(C/C++/Rust)&lt;/strong>&lt;/p>
&lt;pre tabindex="0">&lt;code>优点:
✅ 性能极高 (接近机器码)
✅ 可以复用现有 C/C++ 库
✅ 直接访问硬件
✅ 跨平台代码复用
缺点:
❌ 开发复杂
❌ 调试困难
❌ 需要为不同 CPU 编译
&lt;/code>&lt;/pre>&lt;hr>
&lt;h2 id="ndk工作原理">NDK工作原理
&lt;/h2>&lt;h3 id="完整流程">完整流程
&lt;/h3>&lt;pre tabindex="0">&lt;code>第 1 步: 写 Rust 代码
┌────────────────────────┐
│ // Rust 代码 │
│ pub fn add(a: i32, b: i32) -&amp;gt; i32 {
│ a + b │
│ } │
└────────────────────────┘
↓
第 2 步: NDK 编译
┌────────────────────────┐
│ NDK 工具链编译 │
│ - 交叉编译 │
│ - 针对 ARM/x86 CPU │
└────────────────────────┘
↓
第 3 步: 生成 .so 文件
┌────────────────────────┐
│ librust_lib.so │
│ (机器码,可直接运行) │
└────────────────────────┘
↓
第 4 步: Android 加载
┌────────────────────────┐
│ System.loadLibrary(&amp;#34;rust_lib&amp;#34;)
│ │
│ external fun add(a: Int, b: Int): Int
└────────────────────────┘
↓
第 5 步: JNI 调用
┌────────────────────────┐
│ Kotlin → JNI → Rust │
│ val result = add(5, 3) │
│ // result = 8 │
└────────────────────────┘
&lt;/code>&lt;/pre>&lt;hr>
&lt;h2 id="ndk包含什么">NDK包含什么？
&lt;/h2>&lt;h3 id="ndk工具集">NDK工具集
&lt;/h3>&lt;pre tabindex="0">&lt;code>$ANDROID_NDK_HOME/
├── build/ # 构建脚本
├── toolchains/ # 编译器工具链
│ ├── aarch64-linux-android/ # ARM64 编译器
│ ├── arm-linux-androideabi/ # ARM32 编译器
│ ├── x86/ # x86 编译器
│ └── x86_64/ # x86_64 编译器
├── platforms/ # Android API 级别的头文件
├── sources/ # 示例代码
└── sysroot/ # 系统库
&lt;/code>&lt;/pre>&lt;h3 id="编译器">编译器
&lt;/h3>&lt;pre tabindex="0">&lt;code>NDK 提供了针对不同 CPU 架构的编译器:
ARM64 (arm64-v8a): 现代手机 (主流)
ARM32 (armeabi-v7a): 老手机
x86: 模拟器
x86_64: 模拟器
&lt;/code>&lt;/pre>&lt;hr>
&lt;h2 id="so文件是什么">.so文件是什么？
&lt;/h2>&lt;h3 id="理解so文件">理解.so文件
&lt;/h3>&lt;pre tabindex="0">&lt;code>.so = Shared Object (共享对象)
类似于:
- Windows 的 .dll 文件
- macOS 的 .dylib 文件
作用:
- 包含编译后的机器码
- 可以被多个程序共享使用
&lt;/code>&lt;/pre>&lt;h3 id="so文件示例">.so文件示例
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 查看 .so 文件&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ls android/app/src/main/jniLibs/arm64-v8a/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># librust_lib.so ← 这就是编译后的 Rust 代码&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 查看文件信息&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">file librust_lib.so
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># librust_lib.so: ELF 64-bit LSB shared object, ARM aarch64, ...&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 查看导出的函数&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">nm -D librust_lib.so &lt;span class="p">|&lt;/span> grep Java
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Java_com_example_rustdemo_RustBridge_add&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Java_com_example_rustdemo_RustBridge_reverseString&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="开发流程概览">开发流程概览
&lt;/h2>&lt;p>完整环境安装、Rust target、&lt;code>cargo-ndk&lt;/code> 和 ABI 输出目录已经单独放在《Rust JNI 环境配置》里。这里保留概念流程：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">Rust 代码
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -&amp;gt; NDK / cargo-ndk 交叉编译
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -&amp;gt; 生成对应 ABI 的 .so
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -&amp;gt; 打进 APK/AAB
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -&amp;gt; Kotlin 通过 JNI 或 UniFFI 调用
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="ndk核心概念">NDK核心概念
&lt;/h2>&lt;h3 id="jnijava-native-interface">JNI(Java Native Interface)
&lt;/h3>&lt;p>&lt;strong>JNI&lt;/strong>是桥梁:&lt;/p>
&lt;pre tabindex="0">&lt;code>┌──────────────┐ ┌──────────────┐
│ Kotlin │ JNI │ Rust │
│ (虚拟机) │ ◄─────► │ (原生码) │
└──────────────┘ └──────────────┘
数据传递:
Kotlin Int ↔ Rust i32
Kotlin String ↔ Rust String
Kotlin IntArray ↔ Rust &amp;amp;[i32]
&lt;/code>&lt;/pre>&lt;h3 id="交叉编译">交叉编译
&lt;/h3>&lt;p>什么是交叉编译?&lt;/p>
&lt;pre tabindex="0">&lt;code>你在 x86_64 电脑上开发
↓
但手机是 ARM64 架构
↓
需要&amp;#34;交叉编译&amp;#34;: 在 x86_64 上编译出 ARM64 代码
↓
NDK 提供了交叉编译工具链
&lt;/code>&lt;/pre>&lt;h3 id="abiapplication-binary-interface">ABI(Application Binary Interface)
&lt;/h3>&lt;p>不同&lt;strong>CPU&lt;/strong>需要不同的**.so**文件:&lt;/p>
&lt;pre tabindex="0">&lt;code>arm64-v8a/libmylib.so → ARM64 手机
armeabi-v7a/libmylib.so → ARM32 手机
x86/libmylib.so → x86 模拟器
x86_64/libmylib.so → x86_64 模拟器
&lt;/code>&lt;/pre>&lt;hr>
&lt;h2 id="什么时候用ndk">什么时候用NDK?
&lt;/h2>&lt;h3 id="应该用ndk的场景">应该用NDK的场景
&lt;/h3>&lt;pre tabindex="0">&lt;code>1. 性能关键代码
- 图像/视频处理
- 音频处理
- 大量数学计算
- 加密/解密
2. 复用现有代码
- 已有 C/C++ 库
- 跨平台代码 (iOS/Android 共享)
3. 保护核心算法
- 防止反编译
- 商业逻辑保护
4. 访问底层功能
- 硬件控制
- 系统调用
&lt;/code>&lt;/pre>&lt;h3 id="不应该用ndk的场景">不应该用NDK的场景
&lt;/h3>&lt;pre tabindex="0">&lt;code>1. 简单业务逻辑
- 按钮点击
- 数据展示
- 网络请求
2. 快速开发
- 原型验证
- MVP 阶段
3. 团队不熟悉 C/C++/Rust
- 维护成本高
- Bug 难以调试
&lt;/code>&lt;/pre>&lt;hr>
&lt;h2 id="常用排查工具">常用排查工具
&lt;/h2>&lt;pre tabindex="0">&lt;code># 查看 .so 文件信息
readelf -h libmylib.so
# 查看导出的函数
nm -D libmylib.so
# 反汇编 (调试用)
objdump -d libmylib.so
&lt;/code>&lt;/pre>&lt;hr>
&lt;h2 id="总结">总结
&lt;/h2>&lt;h3 id="ndk是什么">NDK是什么？
&lt;/h3>&lt;pre tabindex="0">&lt;code>NDK = 让你用 C/C++/Rust 开发 Android 的工具包
作用:
1. 提供交叉编译工具链
2. 编译出 .so 机器码文件
3. 通过 JNI 与 Kotlin 交互
4. 获得原生性能
适用场景:
- 高性能计算
- 复用 C/C++ 库
- 跨平台开发
&lt;/code>&lt;/pre>&lt;h3 id="关键概念">关键概念
&lt;/h3>&lt;pre tabindex="0">&lt;code>NDK: 工具包
JNI: 桥梁 (Kotlin ↔ 原生代码)
.so: 编译后的机器码
ABI: 不同 CPU 架构
流程:
Rust 代码 → NDK 编译 → .so 文件 → JNI 调用 → Kotlin 使用
&lt;/code>&lt;/pre></description></item></channel></rss>