Linking in Android NDK (No Java)

I’ve read that it is necessary to call System.loadLibrary from java on android, but I’m using a completely java-free environment (C++ in a Visual Studio 2015 Android, iOS, and Windows Universal project).

Is there any way to load the library using C++?

System.LoadLibrary is required to properly load Android dependencies and ensure they have access to the Java environment. The internals of FMOD use Java to implement some APIs as there is no native equivalent.

I’m not familiar with the native Visual Studio 2015 Android integration but I’d expect there is a way to provide Java code. We use the NVidia Android integration for Visual Studio and it works well allowing both C++ and Java code within the IDE.

Here’s how to make it work with Visual Studio, step by step:

Assumptions: you’ve got only c++ code in a project created in Visual Studio (VS2019 in my case, VS2017 gives the same project) basing on “Native-Activity application (Android)”. You haven’t changed AndroidManifest.xml nor build.xml (maybe only to get assets automatically).

I will be using MyGame in code etc

  1. in packaging project (MyGame.Packaging) create “libs” folder. Add fmod.jar there. Open its properties and choose “Copy to output directory” to be “Copy always”.

  2. in the same project create “src” folder. Add a new file in it, java code, MyGameActivity.java. Its content:

    package com.myPackage;
    
    import android.app.NativeActivity;
    
    public class MyGameActivity extends android.app.NativeActivity
    {
    	static
    	{
    		System.loadLibrary("fmod");
    		System.loadLibrary("fmodstudio");
    	}
    }
    

Go to its properties and set to always copy it (as in 1)

  1. Open AndroidManifest and set hasCode to true:
    <application android:label="@string/app_name" android:hasCode="true">
    and change android:name for activity to your class name (full path):
    <activity android:name="com.myPackage.MyGameActivity"

And that’s it.

You have to use mentioned folder names as build.xml relies on them. If you choose to use different names, you have to either modify build.xml (the original one in SDK folder) or provide dir variables. Assuming its you only java code, keep the names the way they are.

What should happen: build.xml will notice that hasCode is set to true, will then look for .java files in src folder and will compile them creating .class files. After that, it will get both .class file and fmod.jar (from libs folder) and turn it into classes.dex that will end up in apk.

Because android:name is changed and is based on android.app.NativeActivity two things happen:

  1. Both System.loadLibrary calls will get executed, this way fmod will be properly initialised and when calling “initialize” method you won’t get error and info in android log about missing call to JNI_OnLoad .
  2. Your app will run just as it was running before.

How to check if apk was prepared properly. Open apk file (change its extension to .zip and open is as zip) and unpack classes.dex. View it in any text viewer and look for “fmod” and “MyGame”. Both those phrases should be found.

It’s really easy but without any knowledge of how android stuff is built with build.xml you don’t know where to start (I did it the other way around, calling java from C++, then compiling java by hand, creating jars and trying to get them into apk, when I learned that build.xml can do all of that for me).

1 Like