Skip to content

Commit ab8893b

Browse files
committed
Initial android support.
1 parent 42355d2 commit ab8893b

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,13 @@ flutter-engine = { git = "https://github.com/flutter-rs/flutter-rs" }
1010
flutter-winit = { git = "https://github.com/flutter-rs/flutter-rs" }
1111
glutin = { git = "https://github.com/dvc94ch/glutin", branch = "android" }
1212
log = "0.4.8"
13+
14+
[target.'cfg(target_os = "android")'.dependencies]
15+
android_glue = { git = "https://github.com/rust-windowing/android-rs-glue" }
16+
android_logger = "0.8.6"
17+
android-ndk = { git = "https://github.com/rust-windowing/android-ndk-rs" }
18+
jni-glue = "0.0.10"
19+
20+
[target.'cfg(target_os = "android")'.dependencies.jni-android-sys]
21+
version = "0.0.10"
22+
features = ["api-level-18", "android-content-Context", "android-content-pm-ApplicationInfo"]

src/main.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use flutter_winit::FlutterWindow;
22
use glutin::window::WindowBuilder;
33
use std::path::Path;
44

5+
#[cfg(not(target_os = "android"))]
56
fn main() {
67
env_logger::init();
78

@@ -23,3 +24,69 @@ fn main() {
2324

2425
flutter.run();
2526
}
27+
28+
#[cfg(target_os = "android")]
29+
fn main() {
30+
use android_logger::Config;
31+
use android_ndk::android_app::AndroidApp;
32+
use jni_android_sys::android::content::Context;
33+
use log::Level;
34+
use std::ffi::OsStr;
35+
use std::os::unix::ffi::OsStrExt;
36+
use std::path::PathBuf;
37+
38+
android_logger::init_once(
39+
Config::default()
40+
.with_min_level(Level::Debug)
41+
.with_tag("flutter_app_template"),
42+
);
43+
44+
let android_app = unsafe { AndroidApp::from_ptr(android_glue::get_android_app()) };
45+
46+
let assets_dir = PathBuf::from(OsStr::from_bytes(
47+
android_app.activity().internal_data_path().to_bytes(),
48+
));
49+
50+
let mut args = Vec::with_capacity(1);
51+
52+
let vm = unsafe { jni_glue::VM::from_jni_local(&*android_app.activity().vm()) };
53+
54+
let snapshot = vm.with_env(|env| {
55+
let context = Context::new(env).unwrap();
56+
let info = context.getApplicationInfo().unwrap().unwrap();
57+
let lib_dir = info.nativeLibraryDir().unwrap().to_string().unwrap();
58+
Path::new(&lib_dir).join("app.so")
59+
});
60+
61+
if snapshot.exists() {
62+
args.push(format!("--aot-shared-library-name={}", snapshot.display()));
63+
} else {
64+
std::fs::create_dir_all(&assets_dir).unwrap();
65+
copy_asset(
66+
&android_app.activity().asset_manager(),
67+
b"kernel_blob.bin\0",
68+
&assets_dir.join("kernel_blob.bin"),
69+
);
70+
}
71+
72+
let window = WindowBuilder::new().with_title("Flutter App Demo");
73+
let flutter = FlutterWindow::new(window).unwrap();
74+
75+
flutter.start_engine(Path::new(&assets_dir), &args).unwrap();
76+
77+
flutter.run();
78+
}
79+
80+
#[cfg(target_os = "android")]
81+
fn copy_asset(asset_manager: &android_ndk::asset::AssetManager, asset: &[u8], path: &Path) {
82+
use std::ffi::CStr;
83+
use std::io::Read;
84+
85+
let bytes: Vec<u8> = asset_manager
86+
.open(CStr::from_bytes_with_nul(asset).unwrap())
87+
.unwrap()
88+
.bytes()
89+
.collect::<Result<_, _>>()
90+
.unwrap();
91+
std::fs::write(path, bytes).unwrap();
92+
}

0 commit comments

Comments
 (0)