Generate .so file in Android Studio-ThrowExceptions

Exception or error:

I’m aware that there are answers related to this, but they’re old and outdated. I got Android Studio 1.3 and already downloaded Android NDK. When I run an app, it crashes and gives findLibrary returned null in Logcat. I figured out this was due to no .so library file (Correct me if I’m wrong). My question is – How do I generate a .so file in Android Studio?

What I have –

  • Android Studio 1.3 Stable version
  • Gradle 1.5
  • Android Experimental Plugin 0.2

Notice – If the library .so file has to be built from Cygwin or CMD, please tell me how to do it.

How to solve:

There are a few steps needed to get the NDK hooked up into Android Studio. Currently, support is marked as experimental and AS is starting to bundle the ability to download the NDK within the IDE. By default, AS uses a generic Android.mk and Application.mk when source and/or libs are placed in the jni or jniLibs folder. The instructions below override those defaults in order to provide more customization ability.

In short, you will need to:

  1. Create the default jni and jniLibs directories for your source and libs.
  2. Tell Android Studio where to find your NDK build chain
  3. Tell gradle how to compile and where to place your libs
  4. Create an Android.mk file to specify building and linking order
  5. Create some source

Create directories

Inside /app/src/main create a jni and jniLibs directory.

Update local.properties

Inside your local.properties file, add a line similar to:

ndk.dir=/home/nathan/development/bin/android-ndk-r10e

Update build.gradle

This refers to the module level, not the application level. This ensures that we have defined the build path in the step above and removes the ability for Android Studio to automatically invoke ndk-build. Use the following example as a guide.

apply plugin: 'com.android.model.application'

model {
android {
    compileSdkVersion = 23
    buildToolsVersion = "23.0.0"

    defaultConfig.with {
        applicationId = "com.example.hellojni"
        minSdkVersion.apiLevel = 4
        targetSdkVersion.apiLevel = 23
    }
}

compileOptions.with {
    sourceCompatibility=JavaVersion.VERSION_1_7
    targetCompatibility=JavaVersion.VERSION_1_7
}

/*
 * native build settings
 */
android.ndk {
    moduleName = "hello-jni"
    /*
     * Other ndk flags configurable here are
     * cppFlags += "-fno-rtti"
     * cppFlags += "-fno-exceptions"
     * ldLibs    = ["android", "log"]
     * stl       = "system"
     */
}
android.buildTypes {
    release {
        minifyEnabled = false
        proguardFiles  += file('proguard-rules.txt')
    }
}
android.productFlavors {
    // for detailed abiFilter descriptions, refer to "Supported ABIs" @
    // https://developer.android.com/ndk/guides/abis.html#sa
    create("arm") {
        ndk.abiFilters += "armeabi"
    }
    create("arm7") {
        ndk.abiFilters += "armeabi-v7a"
    }
    create("arm8") {
        ndk.abiFilters += "arm64-v8a"
    }
    create("x86") {
        ndk.abiFilters += "x86"
    }
    create("x86-64") {
        ndk.abiFilters += "x86_64"
    }
    create("mips") {
        ndk.abiFilters += "mips"
    }
    create("mips-64") {
        ndk.abiFilters += "mips64"
    }
    // To include all cpu architectures, leaves abiFilters empty
    create("all")
}
}

Android.mk

You will need an Android.mk file inside the /app/src/main/jni directory

LOCAL_PATH := $(call my-dir)

# Builds a dylib out of test.cpp
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := test.cpp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)

test.cpp

Add some awesome C/C++ source code for your lib. These files will start in /app/src/main/jni and will be compiled and linked as specified in your Android.mk

Example file

#include <jni.h>
#include <android/log.h>

static const char *SOME_TAG = "MyAwesomeTag";

extern "C"
{

void
Java_com_something_something_1android_ClassName_some_fn(JNIEnv *env, jobject obj)
{
    __android_log_print(ANDROID_LOG_VERBOSE, SOME_TAG, "Hello from NDK :)");
}

} // End extern

Compile and run.

###

Over a year later with Android Studio 2.2 and above, you can now get all of this done for you for free just by selecting “Include C++ Support” when creating a new project.

For more information check out: https://developer.android.com/studio/projects/add-native-code.html.

Leave a Reply

Your email address will not be published. Required fields are marked *