Android app freezes on text input
Problem
App freezes on Android 13 after writing in input field. Same code works as intended on Linux laptop with Wayland and Gnome.
When the app is first started, it runs fine, but soon after I have entered a few letters in the input field, the whole app stops responding to touch events/freezes, even the virtual keyboard locks.
It seem odd as the app is a super basic view with one input field, one button, and one loop listing all previously added values.
Steps To Reproduce
Steps to reproduce the behavior:
- Follow the guide on https://dioxuslabs.com/learn/0.4/getting_started/mobile to setup an Android build target.
- Use the below lib.rs code
- Deploy to a connected Android phone with $ cargo android run
Expected behavior
The app should handle input elements as on every other web page, it should be possible to type in them.
Screenshots
src/lib.rs
use anyhow::Result;
use dioxus::prelude::*;
#[cfg(target_os = "android")]
use wry::android_binding;
#[cfg(target_os = "android")]
fn init_logging() {
android_logger::init_once(
android_logger::Config::default()
.with_min_level(log::Level::Trace)
.with_tag("dioxus-android-test2"),
);
}
#[cfg(not(target_os = "android"))]
fn init_logging() {
env_logger::init();
}
#[cfg(any(target_os = "android", target_os = "ios"))]
fn stop_unwind<F: FnOnce() -> T, T>(f: F) -> T {
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) {
Ok(t) => t,
Err(err) => {
eprintln!("attempt to unwind out of `rust` with err: {:?}", err);
std::process::abort()
}
}
}
#[cfg(any(target_os = "android", target_os = "ios"))]
fn _start_app() {
stop_unwind(|| main().unwrap());
}
#[no_mangle]
#[inline(never)]
#[cfg(any(target_os = "android", target_os = "ios"))]
pub extern "C" fn start_app() {
#[cfg(target_os = "android")]
android_binding!(com_example, dioxus_android_test2, _start_app);
#[cfg(target_os = "ios")]
_start_app()
}
pub fn main() -> Result<()> {
init_logging();
dioxus_desktop::launch_cfg(
app,
dioxus_desktop::Config::default().with_custom_index(r#"<!DOCTYPE html>
<html>
<head>
<title>Dioxus app</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
</head>
<body>
<div id="main"></div>
</body>
</html>
"#.into()),
);
Ok(())
}
fn app(cx: Scope) -> Element {
let items = use_state(cx, Vec::new);
let number = use_state(cx, || 0.0);
cx.render(rsx! {
h1 { "Numbers"}
form {
onsubmit: move |_| {
if number.get() <= &0.0 {
return;
}
items.modify(|items| {
let mut items = items.clone();
items.push(*number.get());
number.set(0.0);
items
});
},
input {
r#type: "number",
name: "text",
value: "{number}",
oninput: move |ev| {
if let Ok(value) = ev.value.parse() {
number.set(value);
}
}
}
button { r#type: "submit", value: "Save", "Save" }
}
for item in items.iter() {
div { "- {item}" }
}
})
}
Cargo.toml
[package]
name = "dioxus-android-test"
version = "0.1.0"
edition = "2018"
[lib]
crate-type = ["staticlib", "cdylib", "rlib"]
[[bin]]
name = "dioxus-android-test-desktop"
path = "gen/bin/desktop.rs"
[package.metadata.cargo-android]
app-activity-name = "com.example.dioxus_android_test.MainActivity"
app-dependencies = [
"androidx.webkit:webkit:1.6.1",
"androidx.appcompat:appcompat:1.6.1",
"com.google.android.material:material:1.8.0",
]
project-dependencies = ["org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21"]
app-plugins = ["org.jetbrains.kotlin.android"]
app-permissions = ["android.permission.INTERNET"]
app-theme-parent = "Theme.MaterialComponents.DayNight.DarkActionBar"
vulkan-validation = false
[package.metadata.cargo-android.env-vars]
WRY_ANDROID_PACKAGE = "com.example.dioxus_android_test"
WRY_ANDROID_LIBRARY = "dioxus_android_test"
WRY_ANDROID_KOTLIN_FILES_OUT_DIR = "<android-project-dir>/app/src/main/kotlin/com/example/dioxus_android_test"
[package.metadata.cargo-apple.ios]
frameworks = ["WebKit"]
[dependencies]
anyhow = "1.0.56"
dioxus = "0.4.3"
dioxus-desktop = "0.4.3"
log = "0.4.11"
wry = "0.28.3"
[target.'cfg(target_os = "android")'.dependencies]
android_logger = "0.13.3"
jni = "0.21.1"
paste = "1.0"
[target.'cfg(not(target_os = "android"))'.dependencies]
env_logger = "0.11.0"
[target.'cfg(target_os = "ios")'.dependencies]
core-foundation = "0.9.3"
Environment:
- Dioxus version: 0.4.3
- Rust version: 1.75.0
- OS info: Android 13, built on Arch Linux with kernel 6.7.0
- App platform: mobile
Questionnaire
- [ ] I'm interested in fixing this myself but don't know where to start
- [ ] I would like to fix and I have a solution
- [x] I don't have time to fix this right now, but maybe later
This looks very similar to #1158. If it is the same issue, you can follow this version of the guide which uses the git version of dioxus to fix it https://github.com/DioxusLabs/docsite/pull/191
@ealmloff thank you for the guidance!
I followed Android part of the updated guide you linked (https://github.com/DioxusLabs/docsite/blob/7f57a13d28e4d5d47c6fd9e3022fb1d2989aee1b/docs-src/0.4/en/getting_started/mobile.md) as closely as possible.
I now get a dependency conflict:
gui on main [?] is 📦 v0.1.0 via 🦀 v1.75.0
❯ cargo android build
Updating crates.io index
Updating git repository `https://github.com/dioxuslabs/dioxus`
error: failed to select a version for `gdk-sys`.
... required by package `gdkwayland-sys v0.18.0`
... which satisfies dependency `gdkwayland-sys = "^0.18.0"` of package `tao v0.24.0`
... which satisfies dependency `tao = "^0.24.0"` of package `dioxus-desktop v0.4.3 (https://github.com/dioxuslabs/dioxus#16c59b8e)`
... which satisfies git dependency `dioxus-desktop` of package `androidtest v0.1.0 (/home/user/projects/androidtest/gui)`
versions that meet the requirements `^0.18` are: 0.18.0
the package `gdk-sys` links to the native library `gdk-3`, but it conflicts with a previous package which links to `gdk-3` as well:
package `gdk-sys v0.16.0`
... which satisfies dependency `gdk = "^0.16"` of package `gtk-sys v0.16.0`
... which satisfies dependency `gtk-sys = "^0.16"` of package `rfd v0.11.3`
... which satisfies dependency `rfd = "^0.11.3"` of package `dioxus-desktop v0.4.3`
... which satisfies dependency `dioxus-desktop = "^0.4.3"` of package `app v0.1.0 (/home/user/projects/androidtest/app)`
Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the links ='gdk-sys' value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.
failed to select a version for `gdk-sys` which could resolve this conflict
error: Failed to compile lib
`Failed to run `cargo build`: command ["cargo", "build", "--package", "androidtest", "--manifest-path", "/home/user/
projects/androidtest/gui/Cargo.toml", "--target", "aarch64-linux-android"] exited with code 101
I don't have time to do extensive testing right now, but I'll try a bit more later on.