use jni::{objects::JObject, JNIEnv, JavaVM};
use std::sync::OnceLock;
static ACTIVITY: OnceLock<jni::objects::GlobalRef> = OnceLock::new();
static JAVA_VM: OnceLock<JavaVM> = OnceLock::new();
pub fn with_activity<F, R>(f: F) -> Option<R>
where
F: FnOnce(&mut JNIEnv<'_>, &JObject<'_>) -> Option<R>,
{
let ctx = ndk_context::android_context();
let vm = if let Some(vm) = JAVA_VM.get() {
vm
} else {
let raw_vm = unsafe { JavaVM::from_raw(ctx.vm().cast()) }.ok()?;
let _ = JAVA_VM.set(raw_vm);
JAVA_VM.get()?
};
let mut env = vm.attach_current_thread().ok()?;
let activity = if let Some(activity) = ACTIVITY.get() {
activity
} else {
let raw_activity = unsafe { JObject::from_raw(ctx.context() as jni::sys::jobject) };
let global = env.new_global_ref(&raw_activity).ok()?;
match ACTIVITY.set(global) {
Ok(()) => ACTIVITY.get().unwrap(),
Err(global) => {
drop(global);
ACTIVITY.get()?
}
}
};
let activity_obj = activity.as_obj();
f(&mut env, &activity_obj)
}