From 9b56b28c2174a2c61dc30ceeb8e1c25add6620fb Mon Sep 17 00:00:00 2001 From: deteam Date: Mon, 13 Apr 2026 14:50:33 +0200 Subject: [PATCH 1/2] fix: release REQUEST_HANDLER sooner on Android Attempting to speed up assets loading on Android with this --- src/android/binding.rs | 10 ++++++++-- src/android/mod.rs | 6 +++--- src/lib.rs | 6 +++--- src/wkwebview/mod.rs | 3 ++- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/android/binding.rs b/src/android/binding.rs index 031cd09cc..726064eb3 100644 --- a/src/android/binding.rs +++ b/src/android/binding.rs @@ -99,7 +99,13 @@ fn handle_request( let webview_id = env.get_string(&webview_id)?; let webview_id = webview_id.to_str().ok().unwrap_or_default(); - if let Some(handler) = REQUEST_HANDLER.lock().unwrap().get(webview_id) { + let handler = REQUEST_HANDLER + .lock() + .unwrap() + .get(webview_id) + .map(|handler| handler.handler.clone()); + + if let Some(handler) = handler { #[cfg(feature = "tracing")] let span = tracing::info_span!(parent: None, "wry::custom_protocol::handle", uri = tracing::field::Empty).entered(); @@ -162,7 +168,7 @@ fn handle_request( let response = { #[cfg(feature = "tracing")] let _span = tracing::info_span!("wry::custom_protocol::call_handler").entered(); - (handler.handler)( + handler( webview_id, final_request, is_document_start_script_enabled != 0, diff --git a/src/android/mod.rs b/src/android/mod.rs index 8f44c7040..99c7f1b24 100644 --- a/src/android/mod.rs +++ b/src/android/mod.rs @@ -21,7 +21,7 @@ use raw_window_handle::HasWindowHandle; use std::{ borrow::Cow, collections::HashMap, - sync::{mpsc::channel, Mutex}, + sync::{mpsc::channel, Arc, Mutex}, time::Duration, }; @@ -70,7 +70,7 @@ macro_rules! define_static_handlers { define_static_handlers! { IPC = UnsafeIpc { handler: Box)> }; - REQUEST_HANDLER = UnsafeRequestHandler { handler: Box>, bool) -> Option>>> }; + REQUEST_HANDLER = UnsafeRequestHandler { handler: Arc>, bool) -> Option>> + Send + Sync> }; TITLE_CHANGE_HANDLER = UnsafeTitleHandler { handler: Box }; URL_LOADING_OVERRIDE = UnsafeUrlLoadingOverride { handler: Box bool> }; ON_LOAD_HANDLER = UnsafeOnPageLoadHandler { handler: Box }; @@ -247,7 +247,7 @@ impl InnerWebView { .unwrap() .insert( id.clone(), - UnsafeRequestHandler::new(Box::new( + UnsafeRequestHandler::new(Arc::new( move |webview_id: &str, mut request, is_document_start_script_enabled| { let uri = request.uri().to_string(); if let Some((custom_protocol, custom_protocol_handler)) = diff --git a/src/lib.rs b/src/lib.rs index bec4295ea..416853a6f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -644,7 +644,7 @@ struct WebViewAttributes<'a> { /// locate your files in those directories. For more information, see [Loading in-app content](https://developer.android.com/guide/webapps/load-local-content) page. /// - iOS: To get the path of your assets, you can call [`CFBundle::resources_path`](https://docs.rs/core-foundation/latest/core_foundation/bundle/struct.CFBundle.html#method.resources_path). So url like `wry://assets/index.html` could get the html file in assets directory. pub custom_protocols: - HashMap>, RequestAsyncResponder)>>, + HashMap>, RequestAsyncResponder) + Send + Sync>>, /// The IPC handler to receive the message from Javascript on webview /// using `window.ipc.postMessage("insert_message_here")` to host Rust code. @@ -1037,7 +1037,7 @@ impl<'a> WebViewBuilder<'a> { #[cfg(feature = "protocol")] pub fn with_custom_protocol(mut self, name: String, handler: F) -> Self where - F: Fn(WebViewId, Request>) -> Response> + 'static, + F: Fn(WebViewId, Request>) -> Response> + Send + Sync + 'static, { #[cfg(any( target_os = "linux", @@ -1102,7 +1102,7 @@ impl<'a> WebViewBuilder<'a> { #[cfg(feature = "protocol")] pub fn with_asynchronous_custom_protocol(mut self, name: String, handler: F) -> Self where - F: Fn(WebViewId, Request>, RequestAsyncResponder) + 'static, + F: Fn(WebViewId, Request>, RequestAsyncResponder) + Send + Sync + 'static, { #[cfg(any( target_os = "linux", diff --git a/src/wkwebview/mod.rs b/src/wkwebview/mod.rs index 685634980..b492a1474 100644 --- a/src/wkwebview/mod.rs +++ b/src/wkwebview/mod.rs @@ -109,7 +109,8 @@ static COUNTER: Counter = Counter::new(); static WEBVIEW_STATE: Lazy>> = Lazy::new(Default::default); struct WebViewState { - pub protocol_ptrs: Vec>, RequestAsyncResponder)>>, + pub protocol_ptrs: + Vec>, RequestAsyncResponder) + Send + Sync>>, } unsafe impl Send for WebViewState {} From 22fa8fb7fd84d4d93b3b7428cfb23c08f6b99fb8 Mon Sep 17 00:00:00 2001 From: deteam Date: Mon, 13 Apr 2026 15:08:22 +0200 Subject: [PATCH 2/2] Update .changes info --- .changes/early-mutex-release.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/early-mutex-release.md diff --git a/.changes/early-mutex-release.md b/.changes/early-mutex-release.md new file mode 100644 index 000000000..abe5ba1fd --- /dev/null +++ b/.changes/early-mutex-release.md @@ -0,0 +1,5 @@ +--- +"wry": minor +--- + +On Android, release REQUEST_HANDLER mutex sooner by cloning the underlying Send + Sync handler.