Struct android_activity::AndroidApp
source · pub struct AndroidApp { /* private fields */ }
Expand description
The top-level state and interface for a native Rust application
AndroidApp
provides an interface to query state for the application as
well as monitor events, such as lifecycle and input events, that are
marshalled between the Java thread that owns the Activity
and the native
thread that runs the android_main()
code.
§Cheaply Clonable AndroidApp
AndroidApp
is intended to be something that can be cheaply passed around
by referenced within an application. It is reference counted and can be
cheaply cloned.
§Send
and Sync
AndroidApp
Although an AndroidApp
implements Send
and Sync
you do need to take
into consideration that some APIs, such as AndroidApp::poll_events()
are
explicitly documented to only be usable from your android_main()
thread.
Implementations§
source§impl AndroidApp
impl AndroidApp
sourcepub fn native_window(&self) -> Option<NativeWindow>
pub fn native_window(&self) -> Option<NativeWindow>
Queries the current NativeWindow
for the application.
This will only return Some(window)
between
MainEvent::InitWindow
and MainEvent::TerminateWindow
events.
sourcepub fn vm_as_ptr(&self) -> *mut c_void
pub fn vm_as_ptr(&self) -> *mut c_void
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:
let vm = unsafe { JavaVM::from_raw(app.vm_as_ptr()) };
sourcepub fn activity_as_ptr(&self) -> *mut c_void
pub fn activity_as_ptr(&self) -> *mut c_void
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:
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.
sourcepub fn poll_events<F>(&self, timeout: Option<Duration>, callback: F)
pub fn poll_events<F>(&self, timeout: Option<Duration>, callback: F)
Polls for any events associated with this AndroidApp and processes those events
(such as lifecycle events) via the given callback
.
It’s important to use this API for polling, and not call ALooper_pollAll
directly since
some events require pre- and post-processing either side of the callback. For correct
behavior events should be handled immediately, before returning from the callback and
not simply queued for batch processing later. For example the existing NativeWindow
is accessible during a MainEvent::TerminateWindow
callback and will be
set to None
once the callback returns, and this is also synchronized with the Java
main thread. The MainEvent::SaveState
event is also synchronized with the
Java main thread.
§Panics
This must only be called from your android_main()
thread and it may panic if called
from another thread.
sourcepub fn create_waker(&self) -> AndroidAppWaker
pub fn create_waker(&self) -> AndroidAppWaker
Creates a means to wake up the main loop while it is blocked waiting for
events within AndroidApp::poll_events()
.
sourcepub fn config(&self) -> ConfigurationRef
pub fn config(&self) -> ConfigurationRef
Returns a (cheaply clonable) reference to this application’s ndk::configuration::Configuration
sourcepub fn content_rect(&self) -> Rect
pub fn content_rect(&self) -> Rect
Queries the current content rectangle of the window; this is the area where the window’s content should be placed to be seen by the user.
sourcepub fn asset_manager(&self) -> AssetManager
pub fn asset_manager(&self) -> AssetManager
Queries the Asset Manager instance for the application.
Use this to access binary assets bundled inside your application’s .apk file.
sourcepub fn set_window_flags(
&self,
add_flags: WindowManagerFlags,
remove_flags: WindowManagerFlags
)
pub fn set_window_flags( &self, add_flags: WindowManagerFlags, remove_flags: WindowManagerFlags )
Change the window flags of the given activity.
Note that some flags must be set before the window decoration is created,
see
<https://developer.android.com/reference/android/view/Window#setFlags(int,%20int)>
.
sourcepub fn enable_motion_axis(&self, axis: Axis)
pub fn enable_motion_axis(&self, axis: Axis)
Enable additional input axis
To reduce overhead, by default only input::Axis::X
and input::Axis::Y
are enabled
and other axis should be enabled explicitly.
sourcepub fn disable_motion_axis(&self, axis: Axis)
pub fn disable_motion_axis(&self, axis: Axis)
Disable input axis
To reduce overhead, by default only input::Axis::X
and input::Axis::Y
are enabled
and other axis should be enabled explicitly.
sourcepub fn show_soft_input(&self, show_implicit: bool)
pub fn show_soft_input(&self, show_implicit: bool)
Explicitly request that the current input method’s soft input area be shown to the user, if needed.
Call this if the user interacts with your view in such a way that they have expressed they would like to start performing input into it.
sourcepub fn hide_soft_input(&self, hide_implicit_only: bool)
pub fn hide_soft_input(&self, hide_implicit_only: bool)
Request to hide the soft input window from the context of the window that is currently accepting input.
This should be called as a result of the user doing some action that fairly explicitly requests to have the input window hidden.
sourcepub fn text_input_state(&self) -> TextInputState
pub fn text_input_state(&self) -> TextInputState
Fetch the current input text state, as updated by any active IME.
sourcepub fn set_text_input_state(&self, state: TextInputState)
pub fn set_text_input_state(&self, state: TextInputState)
Forward the given input text state
to any active IME.
sourcepub fn input_events_iter(&self) -> Result<InputIterator<'_>>
pub fn input_events_iter(&self) -> Result<InputIterator<'_>>
Get an exclusive, lending iterator over buffered input events
Applications are expected to call this in-sync with their rendering or
in response to a MainEvent::InputAvailable
event being delivered.
Note: your application is will only be delivered a single
MainEvent::InputAvailable
event between calls to this API.
To reduce overhead, by default, only input::Axis::X
and input::Axis::Y
are enabled
and other axis should be enabled explicitly via Self::enable_motion_axis
.
This isn’t the most ergonomic iteration API since we can’t return a standard Iterator
:
- This API returns a lending iterator may borrow from the internal buffer of pending events without copying them.
- For each event we want to ensure the application reports whether the event was handled.
§Example
Code to iterate all pending input events would look something like this:
match app.input_events_iter() {
Ok(mut iter) => {
loop {
let read_input = iter.next(|event| {
let handled = match event {
InputEvent::KeyEvent(key_event) => {
// Snip
}
InputEvent::MotionEvent(motion_event) => {
// Snip
}
event => {
// Snip
}
};
handled
});
if !read_input {
break;
}
}
}
Err(err) => {
log::error!("Failed to get input events iterator: {err:?}");
}
}
§Panics
This must only be called from your android_main()
thread and it may panic if called
from another thread.
sourcepub fn device_key_character_map(
&self,
device_id: i32
) -> Result<KeyCharacterMap>
pub fn device_key_character_map( &self, device_id: i32 ) -> Result<KeyCharacterMap>
Lookup the KeyCharacterMap
for the given input device_id
Use KeyCharacterMap::get
to map key codes + meta state into unicode characters
or dead keys that compose with the next key.
§Example
Code to handle unicode character mapping as well as combining dead keys could look some thing like:
let mut combining_accent = None;
// Snip
let combined_key_char = if let Ok(map) = app.device_key_character_map(device_id) {
match map.get(key_event.key_code(), key_event.meta_state()) {
Ok(KeyMapChar::Unicode(unicode)) => {
let combined_unicode = if let Some(accent) = combining_accent {
match map.get_dead_char(accent, unicode) {
Ok(Some(key)) => {
info!("KeyEvent: Combined '{unicode}' with accent '{accent}' to give '{key}'");
Some(key)
}
Ok(None) => None,
Err(err) => {
log::error!("KeyEvent: Failed to combine 'dead key' accent '{accent}' with '{unicode}': {err:?}");
None
}
}
} else {
info!("KeyEvent: Pressed '{unicode}'");
Some(unicode)
};
combining_accent = None;
combined_unicode.map(|unicode| KeyMapChar::Unicode(unicode))
}
Ok(KeyMapChar::CombiningAccent(accent)) => {
info!("KeyEvent: Pressed 'dead key' combining accent '{accent}'");
combining_accent = Some(accent);
Some(KeyMapChar::CombiningAccent(accent))
}
Ok(KeyMapChar::None) => {
info!("KeyEvent: Pressed non-unicode key");
combining_accent = None;
None
}
Err(err) => {
log::error!("KeyEvent: Failed to get key map character: {err:?}");
combining_accent = None;
None
}
}
} else {
None
};
§Errors
Since this API needs to use JNI internally to call into the Android JVM it may return
a error::AppError::JavaError
in case there is a spurious JNI error or an exception
is caught.
sourcepub fn sdk_version() -> i32
pub fn sdk_version() -> i32
The user-visible SDK version of the framework
Also referred to as Build.VERSION_CODES
sourcepub fn internal_data_path(&self) -> Option<PathBuf>
pub fn internal_data_path(&self) -> Option<PathBuf>
Path to this application’s internal data directory
sourcepub fn external_data_path(&self) -> Option<PathBuf>
pub fn external_data_path(&self) -> Option<PathBuf>
Path to this application’s external data directory
Trait Implementations§
source§impl Clone for AndroidApp
impl Clone for AndroidApp
source§fn clone(&self) -> AndroidApp
fn clone(&self) -> AndroidApp
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more