赞
踩
稍作配置,同一份代码横跨 Android & IOS,相比于 React Native 方案更加高性能。除此之外,得益于 Rust 跨平台加持,Rust 部分的代码可在种种场合复用。
这篇文章旨在记录作者尝试结合 Rust 和 Flutter 的过程,且仅为初步尝试。不会涉及诸如:
如何搭建一个 Flutter 开发环境,以及 Dart 语言怎么用
如何搭建一个 Rust 开发环境,以及 Rust 语言怎么学
开头给自己博客打波广告
Rust + Flutter 高性能的跨端尝试blog.idx0.dev- # Download targets for IOS ( 64 bit targets (real device & simulator) )
- rustup target add aarch64-apple-ios x86_64-apple-ios
-
- # Install cargo-lipo to generate the iOS universal library
- cargo install cargo-lipo
这里有一些行之有效的辅助脚本用于更加快捷配置交叉编译工具。
sh sdkmanager --verbose ndk-bundle
如果已经准备好了 Android NDK ,则设置环境变量 $ANDROID_NDK_HOME
```sh2. Create the standalone NDK
sh3. 在 Cargo default config VS 配置 Android 交叉编译工具
sh cat cargo-config.toml >> ~/.cargo/config 执行上述命令后会在 Cargo 默认配置中,增加有关 Android 跨平台目标 (targets, `aarch64-linux-android`, `armv7-linux-androideabi`, `i686-linux-android`) 的工具信息,指向刚刚创建的 `standalone NDK`。
ini [target.aarch64-linux-android] ar = ... linker = ..4. 下载 Rust 支持 Android 交叉编译的依赖
sh rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android ```sh cargo init my-app-base --lib
Cargo.toml
修改 crate-type
ini [lib] name = "my_app_base" crate-type = ["staticlib", "cdylib"]
Rust 构建出来的二进制库,在 IOS 中是静态链接进最终的程序之中,需要对构建 staticlib
的支持;在 Android 是通过动态链接在运行时装在进程序运行空间的,需要对构建 cdylib
的支持。src/lib.rs
hello
函数时,会在晋城堆空间中创建一个字符串 ( CString
),并将所有权 ( 释放该字符串所占堆空间的权利 ) 移交给调用者。- # IOS
- cargo lipo --release
-
- # Android
- cargo build --target aarch64-linux-android --release
- cargo build --target armv7-linux-androideabi --release
- cargo build --target i686-linux-android --release
然后在 target
目录下会得到以下有用的物料。
- target
- ├── aarch64-linux-android
- │ └── release
- │ ├── libmy_app_base.a
- │ └── libmy_app_base.so
- ├── armv7-linux-androideabi
- │ └── release
- │ ├── libmy_app_base.a
- │ └── libmy_app_base.so
- ├── i686-linux-android
- │ └── release
- │ ├── libmy_app_base.a
- │ └── libmy_app_base.so
- ├── universal
- │ └── release
- │ └── libmy_app_base.a
至此, Rust
部分就告于段落了。
- from: target/universal/release/libmy_app_base.a
- to: ios/
-
- from: target/aarch64-linux-android/release/libmy_app_base.so
- to: android/app/src/main/jniLibs/arm64-v8a/
-
- from: target/armv7-linux-androideabi/release/libmy_app_base.so
- to: android/app/src/main/jniLibs/armeabi-v7a/
-
- from: target/i686-linux-android/release/libmy_app_base.so
- to: android/app/src/main/jniLibs/x86/
pubspec.yaml
-> dev_dependencies:
+= ffi: ^0.1.3
flutter run # 如果连接着 Android 设备就直接运行了起来
( 复杂了许多 )
Flutter
官方文档,配置 XCode
项目。Build Phases
中 Link Binary With Libraries
添加 libmy_app_base.a
文件 (按照图上箭头点...) Build Settings
中 Other Linker Flags
中添加 force_load
的参数。 这是由于在 Dart 中通过动态的方式调用了该库的相关函数,但在编译期间静态分析的时候,这些都是未曾被调用过的无用函数,就被剪裁掉了。要通过 force_load
方式解决这个问题。
sudo xattr -d com.apple.quarantine ~/flutter/bin/cache/artifacts/libimobiledevice/ideviceinfo
将后面的路径替换成你的
- dyld: Library not loaded: /b/s/w/ir/k/homebrew/Cellar/libimobiledevice-flutter/HEAD-398c120_3/lib/libimobiledevice.6.dylib
- Referenced from: /Users/hey/flutter/bin/cache/artifacts/libimobiledevice/idevice_id
- Reason: image not found
删除&重新下载
rm -rf /Users/hey/flutter/bin/cache && flutter doctor -v
参见 https://github.com/flutter/flutter/issues/49504#issuecomment-581554697 不要升级到 IOS 13.3.1 系统
介绍了如何构建出 Android, IOS 库,并提供了例子 - https://github.com/TimNN/cargo-lipo
用于构建 universal library - https://github.com/hanabi1224/flutter_native_extensions
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。