Wry on android with winit
lucasmerlin opened this issue · comments
Is your feature request related to a problem? Please describe.
I have a egui project that uses winit and the GameActivity based android-activity backend. I tried to get the android version of wry working in my winit project but unfortunately I didn't succeed.
From the readme it sounds like in theory it should be possible to use wry on android without tao, but it's not really explained how it would work.
I guess the big question is how I would call wry::android_setup()?
I guess the JNIEnv maybe could be constructed from vm_as_ptr?
Same for the activity, activity_as_ptr?
But how would I create the foreign looper?
I also tried creating a tao and a winit instance in parallel, by making the WryActivity extend GameActivity, but then I got a error from ndk-context:
ndk-context-0.1.1/src/lib.rs:87:5:
assertion failed: previous.is_none()
I guess because both winit and tao try to initialize ndk-context.
Describe the solution you'd like
Support to use wry with winit on android, and better documentation how it would be done.
Describe alternatives you've considered
I guess an alternative for me would be to just use tao on android and use it together with https://crates.io/crates/eframe_tao, but I'd prefer to stay with winit since I'm using it with every other platform.
I did a bit of experimenting with android-activity's GameActivity
last week and I got it to work but only If invoke the setup function for WRY in Java code after initialization, AndroidApp::vm_as_ptr
and AndroidApp::activity_as_ptr
also seem promising, but didn't have luck with it, just yet, not sure if I can work on it again soon.
Here is a simple PoC that I got working so far if anyone wants to continue research, first add this function in your Rust (notice that function name must contain your android domain and package name)
#[no_mangle]
pub extern "system" fn Java_co_realfit_agdkmainloop_MainActivity_create<'local>(
env: JNIEnv<'local>,
class: JClass<'local>,
activity: JObject<'local>,
) {
fn try_call_java_main_activity_create<'local>(
mut env: JNIEnv<'local>,
_class: JClass<'local>,
activity: JObject<'local>,
) -> jni::errors::Result<()> {
let webview = env.new_object(
"android/webkit/WebView",
"(Landroid/content/Context;)V",
&[(&activity).into()],
)?;
let url = env.new_string("https://tauri.app")?;
env.call_method(
&webview,
"loadUrl",
"(Ljava/lang/String;)V",
&[(&url).into()],
)?;
env.call_method(
activity,
"setContentView",
"(Landroid/view/View;)V",
&[(&webview).into()],
)?;
Ok(())
}
if let Err(err) = try_call_java_main_activity_create(env, class, activity) {
error!("{}", err);
}
}
then in MainActivity.java
, declare this external function:
private native void create(MainActivity activity);
then call it in the onCreate
method:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
create(this);
}