mirror of
https://github.com/rust-mobile/android-activity.git
synced 2026-07-04 05:47:26 +00:00
Add AndroidApp::vm_as_ptr() and ::activity_as_ptr() APIs
This enables applications to make JNI calls without needing the `ndk-context` crate - which we would like to deprecate. Fixes: #60
This commit is contained in:
@@ -3,6 +3,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Added `AndroidApp::vm_as_ptr()` to expose JNI `JavaVM` pointer ([#60](https://github.com/rust-mobile/android-activity/issues/60))
|
||||
- Added `AndroidApp::activity_as_ptr()` to expose Android `Activity` JNI reference as pointer ([#60](https://github.com/rust-mobile/android-activity/issues/60))
|
||||
|
||||
## [0.4] - 2022-11-10
|
||||
### Changed
|
||||
|
||||
@@ -12,6 +12,7 @@ use std::sync::{Arc, RwLock};
|
||||
use std::time::Duration;
|
||||
use std::{ptr, thread};
|
||||
|
||||
use libc::c_void;
|
||||
use log::{error, trace, Level};
|
||||
|
||||
use jni_sys::*;
|
||||
@@ -155,6 +156,16 @@ pub struct AndroidAppInner {
|
||||
}
|
||||
|
||||
impl AndroidAppInner {
|
||||
pub fn vm_as_ptr(&self) -> *mut c_void {
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
unsafe { (*(*app_ptr).activity).vm as _ }
|
||||
}
|
||||
|
||||
pub fn activity_as_ptr(&self) -> *mut c_void {
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
unsafe { (*(*app_ptr).activity).javaGameActivity as _ }
|
||||
}
|
||||
|
||||
pub fn native_window(&self) -> Option<NativeWindow> {
|
||||
self.native_window.read().unwrap().clone()
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ use std::sync::Arc;
|
||||
use std::sync::RwLock;
|
||||
use std::time::Duration;
|
||||
|
||||
use libc::c_void;
|
||||
use ndk::asset::AssetManager;
|
||||
use ndk::native_window::NativeWindow;
|
||||
|
||||
@@ -472,6 +473,49 @@ impl AndroidApp {
|
||||
self.inner.read().unwrap().native_window()
|
||||
}
|
||||
|
||||
/// Returns a pointer to the Java Virtual Machine, for making JNI calls
|
||||
///
|
||||
/// This returns a pointer to the Java Virtual Machine which can be used
|
||||
/// with the [`jni`] crate (or similar crates) to make JNI calls that bridge
|
||||
/// between native Rust code and Java/Kotlin code running within the JVM.
|
||||
///
|
||||
/// If you use the [`jni`] crate you can wrap this as a [`JavaVM`] via:
|
||||
/// ```ignore
|
||||
/// # use jni::JavaVM;
|
||||
/// # let app: AndroidApp = todo!();
|
||||
/// let vm = unsafe { JavaVM::from_raw(app.vm_as_ptr()) };
|
||||
/// ```
|
||||
///
|
||||
/// [`jni`]: https://crates.io/crates/jni
|
||||
/// [`JavaVM`]: https://docs.rs/jni/latest/jni/struct.JavaVM.html
|
||||
pub fn vm_as_ptr(&self) -> *mut c_void {
|
||||
self.inner.read().unwrap().vm_as_ptr()
|
||||
}
|
||||
|
||||
/// Returns a JNI object reference for this application's JVM `Activity` as a pointer
|
||||
///
|
||||
/// If you use the [`jni`] crate you can wrap this as an object reference via:
|
||||
/// ```ignore
|
||||
/// # use jni::objects::JObject;
|
||||
/// # let app: AndroidApp = todo!();
|
||||
/// let activity = unsafe { JObject::from_raw(app.activity_as_ptr()) };
|
||||
/// ```
|
||||
///
|
||||
/// # JNI Safety
|
||||
///
|
||||
/// Note that the object reference will be a JNI global reference, not a
|
||||
/// local reference and it should not be deleted. Don't wrap the reference
|
||||
/// in an [`AutoLocal`] which would try to explicitly delete the reference
|
||||
/// when dropped. Similarly, don't wrap the reference as a [`GlobalRef`]
|
||||
/// which would also try to explicitly delete the reference when dropped.
|
||||
///
|
||||
/// [`jni`]: https://crates.io/crates/jni
|
||||
/// [`AutoLocal`]: https://docs.rs/jni/latest/jni/objects/struct.AutoLocal.html
|
||||
/// [`GlobalRef`]: https://docs.rs/jni/latest/jni/objects/struct.GlobalRef.html
|
||||
pub fn activity_as_ptr(&self) -> *mut c_void {
|
||||
self.inner.read().unwrap().activity_as_ptr()
|
||||
}
|
||||
|
||||
/// Polls for any events associated with this [AndroidApp] and processes those events
|
||||
/// (such as lifecycle events) via the given `callback`.
|
||||
///
|
||||
|
||||
@@ -5,6 +5,7 @@ use std::ptr::NonNull;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::time::Duration;
|
||||
|
||||
use libc::c_void;
|
||||
use log::{error, trace};
|
||||
|
||||
use ndk_sys::ALooper_wake;
|
||||
@@ -130,6 +131,15 @@ pub(crate) struct AndroidAppInner {
|
||||
}
|
||||
|
||||
impl AndroidAppInner {
|
||||
pub(crate) fn vm_as_ptr(&self) -> *mut c_void {
|
||||
unsafe { (*self.native_activity.activity).vm as _ }
|
||||
}
|
||||
|
||||
pub(crate) fn activity_as_ptr(&self) -> *mut c_void {
|
||||
// "clazz" is a completely bogus name; this is the _instance_ not class pointer
|
||||
unsafe { (*self.native_activity.activity).clazz as _ }
|
||||
}
|
||||
|
||||
pub(crate) fn native_activity(&self) -> *const ndk_sys::ANativeActivity {
|
||||
self.native_activity.activity
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user