DioxusLabs / DioxusLabs/dioxus

`with_activity` Android utility assumes `ndk-context` provides `Activity` ref (undocumented + changing)

Open
#5,356 4 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
39.1k
Forks
1.9k
Avg merge
4d 10h
Merged PRs (30d)
4

Description

Hi, I've recently been reviewing crates that use the `ndk-context` API to ensure they are not making any assumptions that the `Context` reference comes from an `Activity` reference.

I've noticed that the `manganis` package appears to make this assumption via the `with_activity` utility that was added in https://github.com/DioxusLabs/dioxus/pull/4842

As it is currently, the `ndk-context` API only promises to provide an `application.content.Context` reference and does not specifically guarantee that this context comes from an `Activity`.

As an implementation detail `android-activity` does currently initialise `ndk-context` with an `Activity`-based context reference but we need to change this in order to address other bugs that this leads to: https://github.com/rust-mobile/android-activity/issues/228, https://github.com/rust-mobile/android-activity/issues/58

Briefly speaking, Android's application programming model allows an application to have multiple (or zero) Activities per application and the current choice to store an Activity reference in the global, static `ndk-context` state is problematic because:
- `ndk-context` is designed to only be initialized once (it will panic if trying to update its state), so even if you only ever have one Activity at a time, we have no way to reset the `ndk-context` state with a new `Activity` reference
- Since `ndk-context` only exposes a single `Context` reference then in case you have an application that creates multiple Activities then `ndk-context` can only be associated with one of them.
- whatever reference is put into `ndk-context` will need to have a global JNI reference to ensure it remains valid for the lifetime of the program which isn't appropriate for an Activity whose lifetime is only associated with a single thread.

For reference, and as a heads up; the plan (for `android-activity`) is to start initializing `ndk-context` with an `Application` `Context`, which is better aligned with the `ndk-context` design which only supports tracking one-time-initialized global state. (ref: https://github.com/rust-mobile/android-activity/pull/229)

**Expected behavior**

Perhaps `manganis` will actually already work with any `android.content.Context` reference and doesn't strictly need an `Activity` in practice and so it could rename `with_activity` to `with_context`.

Note: that `getAssets` is a Java API that is exposed by any `android.content.Context` and so it would be possible to get to an `AssetManager` via any `Context`.

Technically the `AssetManager` associated with a specific `Activity` could be able to find additional resources in some circumstances (compared to the `Application` `AssetManager`) but it's more likely that there's no difference.

Perhaps the `manganis` crate could have some Android-specific config or initialization API that can be used to explicitly provide it a JNI reference to an `Activity` or maybe an `AssetManager` that is acquired externally - e.g. via `android-activity` (`AndroidApp::activity_as_ptr`) or perhaps via some Java native method / JNI integration with a custom Activity subclass.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.