Skip to content

Commit 53b965f

Browse files
committed
ft: save pointer to main looper before spawning worker thread
1 parent ac2e17e commit 53b965f

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

android-activity/src/lib.rs

+17
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,23 @@ impl AndroidApp {
549549
self.inner.read().unwrap().native_window()
550550
}
551551

552+
/// Returns a pointer to the current looper associated with the main thread
553+
///
554+
/// This is appropriate for posting callbacks that need to run on the UI thread
555+
/// Wrap in an [`ndk::looper::ForeignLooper `]
556+
/// ```ignore
557+
/// # use ndk;
558+
/// # let app: AndroidApp = todo!();
559+
/// let looper = unsafe {
560+
/// let non_null_looper = ptr::NonNull::new(_app.main_looper_as_ptr()).unwrap();
561+
/// ndk::looper::ForeignLooper::from_ptr(non_null_looper)
562+
/// };
563+
/// looper.add_fd_with_callback(todo!(), ndk::looper::FdEvent::INPUT, todo!()).unwrap();
564+
/// ```
565+
pub fn main_looper_as_ptr(&self) -> *mut ndk_sys::ALooper {
566+
self.inner.read().unwrap().main_looper()
567+
}
568+
552569
/// Returns a pointer to the Java Virtual Machine, for making JNI calls
553570
///
554571
/// This returns a pointer to the Java Virtual Machine which can be used

android-activity/src/native_activity/glue.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,7 @@ extern "C" fn ANativeActivity_onCreate(
848848
let rust_glue = jvm_glue.clone();
849849
// Let us Send the NativeActivity pointer to the Rust main() thread without a wrapper type
850850
let activity_ptr: libc::intptr_t = activity as _;
851+
let main_looper_ptr: libc::intptr_t = unsafe { ndk_sys::ALooper_forThread() } as _;
851852

852853
// Note: we drop the thread handle which will detach the thread
853854
std::thread::spawn(move || {
@@ -867,7 +868,7 @@ extern "C" fn ANativeActivity_onCreate(
867868
jvm
868869
});
869870

870-
let app = AndroidApp::new(rust_glue.clone(), jvm.clone());
871+
let app = AndroidApp::new(rust_glue.clone(), jvm.clone(), main_looper_ptr as *mut _);
871872

872873
rust_glue.notify_main_thread_running();
873874

android-activity/src/native_activity/mod.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ impl AndroidAppWaker {
8686
}
8787

8888
impl AndroidApp {
89-
pub(crate) fn new(native_activity: NativeActivityGlue, jvm: CloneJavaVM) -> Self {
89+
pub(crate) fn new(native_activity: NativeActivityGlue, jvm: CloneJavaVM, main_looper_ptr: *mut ndk_sys::ALooper) -> Self {
9090
let mut env = jvm.get_env().unwrap(); // We attach to the thread before creating the AndroidApp
9191

9292
let key_map_binding = match KeyCharacterMapBinding::new(&mut env) {
@@ -103,6 +103,9 @@ impl AndroidApp {
103103
looper: Looper {
104104
ptr: ptr::null_mut(),
105105
},
106+
main_looper: Looper {
107+
ptr: main_looper_ptr
108+
},
106109
key_map_binding: Arc::new(key_map_binding),
107110
key_maps: Mutex::new(HashMap::new()),
108111
input_receiver: Mutex::new(None),
@@ -147,6 +150,9 @@ pub(crate) struct AndroidAppInner {
147150
pub(crate) native_activity: NativeActivityGlue,
148151
looper: Looper,
149152

153+
/// Looper associated with the activy's main thread, sometimes called the UI thread.
154+
main_looper: Looper,
155+
150156
/// Shared JNI bindings for the `KeyCharacterMap` class
151157
key_map_binding: Arc<KeyCharacterMapBinding>,
152158

@@ -179,6 +185,10 @@ impl AndroidAppInner {
179185
self.looper.ptr
180186
}
181187

188+
pub fn main_looper(&self) -> *mut ndk_sys::ALooper {
189+
self.main_looper.ptr
190+
}
191+
182192
pub fn native_window(&self) -> Option<NativeWindow> {
183193
self.native_activity.mutex.lock().unwrap().window.clone()
184194
}

0 commit comments

Comments
 (0)