extra activties manifest decleration
Closed this issue · 15 comments
Hello
i'm trying to declare another activity in the manifest so i can call it using jni, but right now i think (and i may be wrong) Cargo.toml right now isn't declaring more activities and is just configuring the NativeActivity, giving it label, more actions and intent filters, etc
is there a way to declare more activities in manifest ? or this functionality can be added ?
Thank you
https://github.com/rust-windowing/android-ndk-rs/tree/master/cargo-apk#manifest
But it looks like not all arrays are documented as arrays.
Thanks for you response,
alright when i tried to treat the package.metadata.android.application.activity
as an array
[[package.metadata.android.application.activity]]
name = "WebActivity"
i'm getting this error while building the app
Error: Failed to parse config.
Caused by:
invalid type: map, expected a string for key `package.metadata.android` at line 35 column 1
maybe i'm using wrong syntax ? can you give a basic working example of a Cargo.toml file with multiple activities ?
It is actually correct that Cargo.toml
currently only supports a single activity
since it itself will generate the necessary code for that activity. Adding more activities means tapping into the build-system to provide more code that handles these activities (AFAIK) and is usually performed the other way around (by compiling a Rust Native Activity to a library and shoving that into gradle or something).
Turning this into an array means we'll need to have some way to figure out which of the activities listed in Cargo.toml
(if at all, otherwise needs a sensible default) belongs to the current binary artifact so that we can set lib_name
(and maybe other things in the future) correctly.
How are you currently adding the necessary code for those activities to your application?
Just in case I set up a little proof-of-concept, but still not convinced how much sense this makes:
https://github.com/MarijnS95/android-ndk-rs/tree/cargo-multiple-activities
Your proof-of-concept looks good, it looks like what I'm asking for, i wish i could try it now, but I'm currently traveling for few days and will test it then.
But having multiple activities could be useful if one wants to have quick and simple java auth activity and maybe google maps one or webview.
@elkhoudiry the question is, how are you adding the java classes for these activities to the apk generated by cargo-apk?
Hello, although i couldn't make the code run when i cloned your repo after the updates. still getting the same
Caused by:
invalid type: map, expected a string for key `package.metadata.android` at line 35 column 1
but anyway, you can start a normal java activity from a native c++ code like this
void openActivity(android_app *app){
JNIEnv *env;
JavaVM* lJavaVM = app->activity->vm;
app->activity->vm->AttachCurrentThread(&env, NULL);
jobject lNativeActivity = app->activity->clazz;
java_load_classes(env);
jclass intentClass = env->FindClass("android/content/Intent");
jstring actionString =env->NewStringUTF("com.example.helloworldc.Auuth"); // <-- auth activity
jmethodID newIntent = env->GetMethodID(intentClass, "<init>", "()V");
jobject intent = env->AllocObject(intentClass);
env->CallVoidMethod(intent, newIntent);
jmethodID setAction = env->GetMethodID(intentClass, "setAction","(Ljava/lang/String;)Landroid/content/Intent;");
env->CallObjectMethod(intent, setAction, actionString);
jclass activityClass = env->FindClass("android/app/Activity");
jmethodID startActivity = env->GetMethodID(activityClass,"startActivity", "(Landroid/content/Intent;)V");
jobject intentObject = env->NewObject(intentClass,newIntent);
env->CallObjectMethod(intentObject, setAction,actionString);
env->CallVoidMethod(lNativeActivity, startActivity, intentObject);
app->activity->vm->DetachCurrentThread();
}
i did manage to clone the same code in rust-ndk and re open the native activity we get with the app when it launches, (which obviously made the code to be in infinte loop), but it's a poc
even if i could make the update to add activities in array in Cargo.toml file to work, i would end up with an exception that the java class with the same name isn't found in dex files
now we are trying to open a java activity that has WebView it to render web content, but mainly control the app from rust side.
Hello, although i couldn't make the code run when i cloned your repo after the updates. still getting the same
Have you ran cargo install --path cargo-apk
(notice --path
) to install the cargo-apk
from that clone?
even if i could make the update to add activities in array in Cargo.toml file to work, i would end up with an exception that the java class with the same name isn't found in dex files
That is exactly the concern I expressed above: You need some way to embed the java part of your application (classes.dex
) and everything else (resources, assets) in the APK. That's out of scope for android-ndk-rs IMO.
At that point you might be better off building your app inside Android Studio + gradle instead, and use something like https://github.com/mozilla/rust-android-gradle to build + embed the Rust NativeActivity
. Would that work for you?
even if i could make the update to add activities in array in Cargo.toml file to work, i would end up with an exception that the java class with the same name isn't found in dex files
That is exactly the concern I expressed above: You need some way to embed the java part of your application (
classes.dex
) and everything else (resources, assets) in the APK. That's out of scope for android-ndk-rs IMO.
Can't cargo-apk inject a Java file to fix this dex error ?
Something like this:
[[package.metadata.android.application.activity]]
java-file = "../path/to/javafile.java"
Have you ran
cargo install --path cargo-apk
(notice--path
) to install thecargo-apk
from that clone?
i didn't before, but i tried it now again and it's still giving me the same error.
even if i could make the update to add activities in array in Cargo.toml file to work, i would end up with an exception that the java class with the same name isn't found in dex files
That is exactly the concern I expressed above: You need some way to embed the java part of your application (
classes.dex
) and everything else (resources, assets) in the APK. That's out of scope for android-ndk-rs IMO.
i see, well i think i good feature to add is the possibility to inject jar libraries or plain java files to the builder, sometimes it's useful to have native access to camera or gps or any native features.
At that point you might be better off building your app inside Android Studio + gradle instead, and use something like https://github.com/mozilla/rust-android-gradle to build + embed the Rust
NativeActivity
. Would that work for you?
thank you for your great suggestion i will give it a look.
i didn't before, but i tried it now again and it's still giving me the same error.
Then you'll have to share the whole file so that we can scan it for eventual errors.
i see, well i think i good feature to add is the possibility to inject jar libraries or plain java files to the builder, sometimes it's useful to have native access to camera or gps or any native features.
In that case it is more common to build a "normal" Java app including a native library that's usually not a native activity but simply called into through Java native functions and the JNI. If you insist on having a native activity it is still more straightforward to embed that crate in your gradle project than doing it the other way around, do look into that link :)
We kinda want to have it all in rust if possible plus little java code if needed.
Basically we are trying to add android backend for a webview crate (https://github.com/tauri-apps/wry) which exposes a unified rust interface for all platforms.
I know this is out of the usual scope of ndk-rs and cargo-apk but at this point we are weighing our options and whether it is possible or not.
@amrbashir Im curious why you want to add a webview which works through NativeActivity and manually renders results instead of simply using a built in Android WebView?
@707090 I never wanted to manually render results, I wanted to use the built-in Webview
component but we just wanted to create it from rust through JNI. @MarijnS95 pointed out I need to use a normal Android activity and not NativeActivity
and the normal activity needed a java file to be compiled into dex and bundled in the apk.
At the time of creating this issue, I though that cargo-apk
might be able to compile the java code into dex and include it into the apk but I looked at the source code and cargo-apk
uses aapt
to make the apk which can't compile java into dex and now I do understand it is out of cargo-apk
scope.
I am going to use cargo-mobile
instead.
this actually works now with various tools. so closing