dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

Android app freezes on text input

Open tirithen opened this issue 1 year ago • 2 comments

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

tirithen avatar Jan 19 '24 22:01 tirithen

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 avatar Jan 20 '24 14:01 ealmloff

@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.

tirithen avatar Jan 20 '24 16:01 tirithen