在Android Studio中生成.so文件

27

我知道有相关的答案,但它们过时了。我使用Android Studio 1.3并已下载Android NDK,但当我运行应用程序时,它会崩溃,并在Logcat中显示findLibrary返回null。我发现这是由于缺少.so库文件(如果我错了,请纠正我)。我的问题是 - 如何在Android Studio中生成一个.so文件?

我拥有:

  • Android Studio 1.3稳定版本
  • Gradle 1.5
  • Android实验性插件0.2

注意:如果要从CygwinCMD构建库.so文件,请告诉我如何操作。


你能否使用Studio 2.1生成.so文件? - Hunt
2个回答

19

在将NDK集成到Android Studio中需要执行以下几个步骤。目前,支持功能被标记为实验性的,AS开始在IDE中捆绑下载NDK的能力。默认情况下,当源代码和/或库放置在jnijniLibs文件夹中时,AS使用通用的Android.mkApplication.mk。以下说明覆盖了这些默认设置,以提供更多的自定义能力。

简而言之,您需要执行以下操作:

  1. 创建默认的jnijniLibs目录以存放源代码和库。
  2. 告诉Android Studio你的NDK编译链的位置。
  3. 告诉gradle如何编译并指定库的存放位置。
  4. 创建一个Android.mk文件来指定构建和链接顺序。
  5. 创建一些源代码。

创建目录

/app/src/main 目录下创建jnijniLibs目录。

更新local.properties

local.properties文件中添加类似于以下内容的行:

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

更新build.gradle

这是模块级别的设置,而不是应用程序级别的设置。这确保了我们已经在上一步中定义了构建路径,并且移除了Android Studio自动调用ndk-build的功能。请使用以下示例作为指南。

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

/app/src/main/jni目录下需要有一个Android.mk文件。

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

在你的lib中添加一些优秀的C/C++源代码。这些文件将位于/app/src/main/jni目录下,并按照你的Android.mk进行编译和链接。

示例文件

#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

编译并运行。


1
您提供的 Gradle 代码适用于旧版的 Android 插件。新的 Experimental plugin 具有不同的 Gradle 布局。请问能否更新您的Gradle代码?感谢您的回答。 - FadedCoder
@AUnknownHacker,这不一定是新旧编辑的问题。更多的是你想要使用gradle还是makefile来处理你的东西。此外,API 4将无法为某些三元组构建,也无法使用Java v1.7。 - nathansizemore
1
@IgorGanapolsky 你看一下问题的答案,它会一步一步地指导你。 - nathansizemore
2
@nathansizemore 你知道.so文件生成在哪里吗?谢谢。 - Alec
他们的意思是说,他们在_jni_文件夹中有一些C/C++源文件。他们想要做的是构建这个项目并生成.so文件,而不是.APK文件。答案是你需要设置gradle来构建一个库而不是应用程序,然后解压/提取生成的.aar库并在其中找到.so文件。这也是如何获得“classes.jar”的方法。 - DisturbedNeo
显示剩余9条评论

10

2
是的,在很长很长的时间后,Android Studio终于添加了对NDK的完全支持 :) - FadedCoder
1
@FadedCoder 那对于旧项目呢?我还能从哪里选择“包括 C++ 支持”的选项吗?谢谢。 - Hilal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接