rust-mobile/ndk

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 the cargo-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