在Android Studio中使用预建的共享库 [英] Using Pre-built Shared Library in Android Studio

查看:113
本文介绍了在Android Studio中使用预建的共享库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在我的android项目中使用自定义的预构建共享库(基于独立ndk构建为libdynamic.so).我在路径src/main中创建了一个文件夹"jniLibs",然后在其中创建了4个文件夹,即"armeabi","armeabi-v7a","x86","x86_64".我已经将预构建的库放在所有这4个文件夹中.

I need to use a custom prebuilt shared library (built on standalone ndk as libdynamic.so) in my android project. I created a folder "jniLibs" in path src/main and then 4 folders inside that namely "armeabi" "armeabi-v7a" "x86" "x86_64". I have put the prebuilt library inside all these 4 folders.

现在从我的本机代码中,我想调用该库的函数.通过以下方式(包含在cmakelists.txt中的标头):

Now from my native code I want to call a function of this library. In the following way (included header in cmakelists.txt):

extern "C"
JNIEXPORT jstring JNICALL
Java_demo_co_ru_jnilibtest_MainActivity_stringFromJNI(
    JNIEnv *env,
    jobject /* this */) {

     float inv = rsqrt(3);  //FUNCTION FROM LIBRARY (libdynamic.so)

     std::string hello = "Hello ";
     return env->NewStringUTF(hello.c_str());
}

我收到以下错误:

  1. Error:error: cannot find -ldynamic

Error:(19) undefined reference to 'rsqrt(float)'

Error:error: linker command failed with exit code 1 (use -v to see invocation)

似乎没有找到共享库.我在CMakeLists.txt中输入了以下值

It seems that shared library is not getting located. I entered following values in CMakeLists.txt

include_directories( src/main/cpp/include) #include header of libdynamic.so
target_link_libraries(native-lib dynamic)  #dependency of native-lib on libdynamic.so

我在gradle构建(应用程序)中添加了以下其他条目:

I added following additional entries inside my gradle build (app):

defaultConfig {
  ndk{
        abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64'
    }
}

sourceSets {
    main {
        jni.srcDirs = ['src/main/jni', 'src/main/jniLibs/']
    }
}


externalNativeBuild {
    cmake {
        path "CMakeLists.txt"
    }
}

我能够使用android push和android shell成功运行该库.这是使用Android Studio的apk构建引起的.我正在使用Android Studio版本2.3.3.任何帮助都将受到高度赞赏.

I am able to successfully run the library using android push and android shell. It is the apk build using Android Studio that is causing problem. I am using Android Studio version 2.3.3. Any help is highly appreciated.

推荐答案

我能够使用Android.mk(而不是cmake)使其工作.我发布Android.mk的配置和内容,并构建gradle,以防万一有人需要它.

I was able to make it work using Android.mk instead of cmake. I am posting configurations and contents of Android.mk and gradle build just in case any one needs it.

在应用"下创建一个文件夹"jni".创建另一个自定义文件夹"yourlibs",并将所有预先构建的库放在相应的"TARGET_ARCH_ABI"文件夹中的"yourlibs"文件夹中.例如,就我而言:

Create a folder "jni" under "app". Create another custom folder "yourlibs" and put all your pre-built libs inside this "yourlibs" folder in respective "TARGET_ARCH_ABI" folder. For Example, in my case:

  • jni/yourlibs/armeabi/libdynamic.so
  • jni/yourlibs/armeabi-v7a/libdynamic.so
  • jni/yourlibs/x86/libdynamic.so
  • jni/yourlibs/x86_64/libdynamic.so

现在请按照以下步骤操作:

Now follow these steps:

  1. 在"jni"文件夹中创建一个"C"文件,您将在其中调用"libdynamic.so"中定义的函数.将必要的头文件添加到您创建的"C"文件中.对我来说是"uselib.c"和"header.h"
  2. 在"jni"文件夹中创建一个名为"Android.mk"的文件

在Android.mk中添加以下内容

Add following contents in Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := yourlibs/$(TARGET_ARCH_ABI)/libdynamic.so
LOCAL_MODULE := add_prebuilt
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_SRC_FILES  := uselib.c
LOCAL_MODULE     :=  use-lib
LOCAL_SHARED_LIBRARIES := add_prebuilt
include $(BUILD_SHARED_LIBRARY)

将gradle build(应用)文件更新为使用"Android.mk"而不是cmake:

Update gradle build (app) file to use "Android.mk" instead of cmake:

在"android => defaultConfig"内部

Inside "android => defaultConfig"

 ndk{
        abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64'
    }

在"android"内部

Inside "android"

externalNativeBuild {
    ndkBuild {
        path "jni/Android.mk"
    }
}

这将创建一个名为"use-lib"的库,该库使用"libdynamic.so",并将这两个库都打包在apk的lib文件夹中.您可以使用apk分析器(Android Studio => Build => Analyze Apk ...)进行检查.要使用"use-lib",请使用jni调用,例如:

This will make a library called "use-lib" that uses "libdynamic.so" and it will pack both the libraries inside the lib folder of apk. You can check this using apk analyser (Android Studio => Build => Analyse Apk ...). To use "use-lib" use jni call, like:

static {
    System.loadLibrary("use-lib");
}

public native String stringFromJNI(); 

注意:我从C代码中删除了extern"C"语句.

Note: I removed extern "C" statement from the C code.

这篇关于在Android Studio中使用预建的共享库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆