Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [SFML3] with AndroidStudio - GameActivity.initializeNativeCode not found  (Read 15 times)

0 Members and 3 Guests are viewing this topic.

jakub.neruda

  • Newbie
  • *
  • Posts: 2
    • View Profile
Okay, so I am trying to get the most basic SFML hello world program working. I don't have any experience with Android development so I downloaded Android Studio (2024.2.2) and I can get their project templates to work, they execute on my phone, I can debug them, etc.

So this is my setup:
New project -> Game Activity (C++)
Language: Java
Min SDK: API 30 (Android 11)
Build config language: Kotlin DSL
C++ standard: Toolchain default

In gradle.build.kts, I've bumped cmake to version 3.28.1

My CMakeLists.txt, has been adapted from the official example:
Code: [Select]
cmake_minimum_required ( VERSION 3.28.1 )

include ( CPM.cmake )

project("myapp")

CPMAddPackage ( "gh:SFML/SFML#3.0.0" )

add_library(${PROJECT_NAME} SHARED
        main.cpp)

target_link_libraries(${PROJECT_NAME} PRIVATE SFML::Graphics android log)

# The ANativeActivity_onCreate function from SFML::Main needs to be exposed in
# our libsfml-example.so file so that is can be loaded at runtime.
target_link_libraries(${PROJECT_NAME} PUBLIC
        -Wl,--whole-archive
        SFML::Main
        -Wl,--no-whole-archive
)

Note that I'd like to build from source as I don't know what NDK is. I'd like to have as minimal build as possible.

Main.cpp:
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <android/native_activity.h>
#include <jni.h>
#include <SFML/System/NativeActivity.hpp>

int main(int argc, char *argv[])
{
    sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "");
    window.setFramerateLimit(30);

    const sf::Texture texture; // didn&#39;t get to "loading resources part yet"
    sf::Sprite image(texture);
    image.setPosition(sf::Vector2f(window.getSize()) / 2.f);
    image.setOrigin(sf::Vector2f(texture.getSize()) / 2.f);

    while (window.isOpen())
    {
        while (const auto event = window.pollEvent())
        {
            if (event->is<sf::Event::Closed>()) window.close();
        }

        window.clear();
        window.draw(image);
        window.display();
    }
}
 

Everything compiles fine, but when I try to execute the application, it immediately crashes. It succeeds in loading the shared library but I get the following exception:
Code: [Select]
Process: com.example.myapp, PID: 22349
                                                                                                    java.lang.UnsatisfiedLinkError: No implementation found for long com.google.androidgamesdk.GameActivity.initializeNativeCode(java.lang.String, java.lang.String, java.lang.String, android.content.res.AssetManager, byte[]) (tried Java_com_google_androidgamesdk_GameActivity_initializeNativeCode and Java_com_google_androidgamesdk_GameActivity_initializeNativeCode__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Landroid_content_res_AssetManager_2_3B) - is the library loaded, e.g. System.loadLibrary?
                                                                                                    at com.google.androidgamesdk.GameActivity.initializeNativeCode(Native Method)
                                                                                                    at com.google.androidgamesdk.GameActivity.onCreate(GameActivity.java:271)
                                                                                                    at android.app.Activity.performCreate(Activity.java:8732)
                                                                                                    at android.app.Activity.performCreate(Activity.java:8710)
                                                                                                    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)
                                                                                                    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3880)
                                                                                                    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4042)
                                                                                                    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
                                                                                                    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
                                                                                                    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
                                                                                                    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2548)
                                                                                                    at android.os.Handler.dispatchMessage(Handler.java:111)
                                                                                                    at android.os.Looper.loopOnce(Looper.java:242)
                                                                                                    at android.os.Looper.loop(Looper.java:362)
                                                                                                    at android.app.ActivityThread.main(ActivityThread.java:8407)
                                                                                                    at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
                                                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:992)

I assume it means the appropriate functions are missing in the shared library, but I can't figure out what's missing. I even tried setting the following, based on the advice from developer.android.com migration guide:
Code: [Select]
set(CMAKE_SHARED_LINKER_FLAGS
        "${CMAKE_SHARED_LINKER_FLAGS} -u \
    Java_com_google_androidgamesdk_GameActivity_initializeNativeCode")

Can anybody help?
« Last Edit: February 22, 2025, 05:33:12 pm by jakub.neruda »

jakub.neruda

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: [SFML3] with AndroidStudio - GameActivity.initializeNativeCode not found
« Reply #1 on: February 22, 2025, 06:16:58 pm »
So I've realized my mistake and now I have a working build. I was confused by the lack of any java file in the official SFML example, seems like it is using one of the library objects.

Furthermore, it is using NativeActivity which differs from GameActivity, so using the Game Activity project type was not the right call.

The easiest way to get everything working is probably downloading the example from the repo, load it as is into the Android studio and then replace the CMakeLists.txt file with what I had created (fetching the repo through CPM and building from source). And it works!