Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using pre-built libraries and jni in Android Studio

I’m using android studio 1.0.2 and I’m trying to create an android library that uses ndk and natives functions. This is basically the architecture of my project:

MyProject
---| MyAndroidApp
---| MyAndroidLibrary
    ---| jni
    ---| jniLibs

In my android library, I have a single c++ wrapper that calls functions from a shared library. I created this library with ndk-build (it works perfectly with eclipse). I added this library in the jniLibs folder/architectures (arm64-v8a, armeabi, armeabi-v7a, mips, mips64, x86 and x86_64). I defined the following Flavors in my MyAndroidLibrary/build.gradle:

productFlavors {
    x86 {
        flavorDimension "abi"
        ndk {
            abiFilter "x86"
        }
    }
    arm {
        flavorDimension "abi"
        ndk {
            abiFilter "armeabi-v7a"
        }
    }
    mips {
        flavorDimension "abi"
        ndk {
            abiFilter "mips"
        }
    }
    fat {
        flavorDimension "abi"
    }
}

However, when I try to call my library functions from the jni code, I get an undefined reference error. In other words, my shared library seems to be not loaded on jni side. But, when I remove the call of these function and I explore the .aar that is created in output, I can retrieve the library .so.

I’m not very familiar with gradle stuff, so I’m not sure about what it really build.

What I’m looking for is a strict equivalent of that Android.mk, using gradle:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE            := mysharedlib
LOCAL_SRC_FILES         := ../shared/mysharedlib.so
LOCAL_EXPORT_C_INCLUDES := ../shared/includes/mysharedlib.h

include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE            := jni
LOCAL_SRC_FILES         := jni.cpp
LOCAL_C_INCLUDES        += ../shared/includes/mysharedlib.h
LOCAL_LDLIBS            := -llog
LOCAL_SHARED_LIBRARIES  := mysharedlib

include $(BUILD_SHARED_LIBRARY)

I would like to call functions from a pre-built library on my jni code, e.g.:

#include "MyDLL.h"

JNIEXPORT jint JNICALL Java_com_iskn_dbapi_DBAPI_getNegative(JNIEnv *env, jclass obj, jint integer)
{
   return MyDLL::getNegative(integer);
}

Thank you for your answers.

like image 997
Sierra Avatar asked Nov 09 '22 19:11

Sierra


1 Answers

Currently gradle plugin don't support such NDK configuration. It ignore existing Android.mk and generate own one (very limited) on the fly. You can see here how it generates (look into writeMakefile method) and assess on your own how limited is set of options, affecting its generation.

Practically, to achieve what you need, the best way would be to completely disable gradle limited NDK support and call ndk-build explicitly. Read here for details.

like image 102
Dmitry Moskalchuk Avatar answered Nov 14 '22 23:11

Dmitry Moskalchuk