简体   繁体   English

Android studio,gradle和NDK

[英]Android studio, gradle and NDK

I am very new to this whole gradle and Android Studio support. 我对这整个Gradle和Android Studio支持都很陌生。 I have managed to convert my android project to gradle using the export option. 我已设法使用导出选项将我的android项目转换为gradle。

But I am looking for some documentation or start point how to integrate the NDK build into the gradle build process. 但我正在寻找一些文档或开始如何将NDK构建集成到gradle构建过程中。

If possible I also need some sort of "after" stage that copies the build binaries (.so files) to the asset directory. 如果可能的话,我还需要某种“后”阶段,将构建二进制文件(.so文件)复制到资产目录。

We have released a first version of the integration as a preview in 1.3: http://tools.android.com/tech-docs/android-ndk-preview 我们在1.3中发布了第一版集成作为预览: http//tools.android.com/tech-docs/android-ndk-preview

The integration will stay a preview even after 1.3 becomes final. 即使在1.3成为最终版之后,集成仍将保持预览。 No current ETA as to when it'll be final (as of 2015/07/10). 目前没有关于何时最终的ETA(截至2015/07/10)。

More information here: http://tools.android.com/tech-docs/android-ndk-preview 更多信息请访问: http//tools.android.com/tech-docs/android-ndk-preview

UPDATE: The Android Studio with NDK support is out now: http://tools.android.com/tech-docs/android-ndk-preview 更新:支持NDK的Android Studio现已推出: http//tools.android.com/tech-docs/android-ndk-preview

For building with a script the gradle solution below should work: 对于使用脚本构建,下面的gradle解决方案应该有效:

I am using my build script and added to my file (Seems to work for 0.8+ ): This seems to be equivalent to the solution below (but looks nicer in the gradle file): 我正在使用我的构建脚本并添加到我的文件中(似乎工作为0.8+ ):这似乎等同于下面的解决方案(但在gradle文件中看起来更好):

 android {
    sourceSets {
        main {
            jniLibs.srcDirs = ['native-libs']
            jni.srcDirs = [] //disable automatic ndk-build
        }
    }
 }

The build unfortunately does not fail if the directory is not present or contains no .so files. 遗憾的是,如果目录不存在或者不包含.so文件,则构建不会失败。

With the update of Android Studio to 1.0, the NDK toolchain support improved immensely ( note: please read my updates at the bottom of this post to see usage with the new experimental Gradle plugin and Android Studio 1.5 ). 随着Android Studio更新到1.0,NDK工具链支持得到了极大的改进( 注意:请阅读本文底部的更新,了解新实验性Gradle插件和Android Studio 1.5的使用情况 )。

Android Studio and the NDK are integrated well enough so that you just need to create an ndk{} block in your module's build.gradle, and set your source files into the (module)/src/main/jni directory - and you're done! Android Studio和NDK集成得非常好,您只需要在模块的build.gradle中创建一个ndk {}块,并将源文件设置到(module)/ src / main / jni目录中 - 你就是完成了!

No more ndk-build from the command line. 从命令行不再有ndk-build。

I've written all about it in my blog post here: http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/ 我在我的博客文章中写了所有相关内容: http//www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/

The salient points are: 重点是:

There are two things you need to know here. 这里有两件事你需要知道。 By default, if you have external libs that you want loaded into the Android application, they are looked for in the (module)/src/main/jniLibs by default. 默认情况下,如果您希望将外部库加载到Android应用程序中,则默认情况下会在(模块)/ src / main / jniLibs中查找它们。 You can change this by using setting sourceSets.main.jniLibs.srcDirs in your module's build.gradle. 您可以通过在模块的build.gradle中设置sourceSets.main.jniLibs.srcDirs来更改此设置。 You'll need a subdirectory with libraries for each architecture you're targeting (eg x86, arm, mips, arm64-v8a, etc…) 您需要一个子目录,其中包含您要定位的每个体系结构的库(例如x86,arm,mips,arm64-v8a等等)

The code you want to be compiled by default by the NDK toolchain will be located in (module)/src/main/jni and similarly to above, you can change it by setting sourceSets.main.jni.srcDirs in your module's build.gradle 您希望NDK工具链默认编译的代码将位于(module)/ src / main / jni中,与上面类似,您可以通过在模块的build.gradle中设置sourceSets.main.jni.srcDirs来更改它。

and put this into your module's build.gradle: 并将其放入模块的build.gradle中:

ndk {
  moduleName "SeePlusPlus" // Name of C++ module (i.e. libSeePlusPlus)
  cFlags "-std=c++11 -fexceptions" // Add provisions to allow C++11 functionality
  stl "gnustl_shared" // Which STL library to use: gnustl or stlport
}

That's the process of compiling your C++ code, from there you need to load it, and create wrappers - but judging from your question, you already know how to do all that, so I won't re-hash. 这是编译C ++代码的过程,从那里你需要加载它,并创建包装器 - 但从你的问题判断,你已经知道如何做所有这些,所以我不会重新哈希。

Also, I've placed a Github repo of this example here: http://github.com/sureshjoshi/android-ndk-swig-example 另外,我在这里放置了一个这个例子的Github回购: http//github.com/sureshjoshi/android-ndk-swig-example

UPDATE: June 14, 2015 更新:2015年6月14日

When Android Studio 1.3 comes out, there should be better support for C++ through the JetBrains CLion plugin. 当Android Studio 1.3问世时,应该通过JetBrains CLion插件更好地支持C ++。 I'm currently under the assumption that this will allow Java and C++ development from within Android Studio; 我目前假设这将允许在Android Studio中进行Java和C ++开发; however I think we'll still need to use the Gradle NDK section as I've stated above. 但是我认为我们仍然需要使用Gradle NDK部分,如上所述。 Additionally, I think there will still be the need to write Java<->C++ wrapper files, unless CLion will do those automatically. 另外,我认为仍然需要编写Java < - > C ++包装器文件,除非CLion会自动执行这些操作。

UPDATE: January 5, 2016 更新:2016年1月5日

I have updated my blog and Github repo (in the develop branch) to use Android Studio 1.5 with the latest experimental Gradle plugin (0.6.0-alpha3). 我更新了我的博客和Github repo(在开发分支中),使用Android Studio 1.5和最新的实验性Gradle插件(0.6.0-alpha3)。

http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/ http://github.com/sureshjoshi/android-ndk-swig-example http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/ http://github.com/sureshjoshi/android-ndk-swig-example

The Gradle build for the NDK section now looks like this: NDK部分的Gradle构建现在看起来像这样:

android.ndk {
    moduleName = "SeePlusPlus" // Name of C++ module (i.e. libSeePlusPlus)
    cppFlags.add("-std=c++11") // Add provisions to allow C++11 functionality
    cppFlags.add("-fexceptions")
    stl = "gnustl_shared" // Which STL library to use: gnustl or stlport
}

Also, quite awesomely, Android Studio has auto-complete for C++-Java generated wrappers using the 'native' keyword: 此外,非常棒的是,Android Studio已经自动完成了C ++ - 使用'native'关键字生成Java包装器:

自动完成C ++的例子 -  Java包装器

However, it's not completely rosy... If you're using SWIG to wrap a library to auto-generate code, and then try to use the native keyword auto-generation, it will put the code in the wrong place in your Swig _wrap.cxx file... So you need to move it into the "extern C" block: 但是,它并不完全乐观......如果您使用SWIG将库包装为自动生成代码,然后尝试使用native关键字自动生成,它会将代码放在Swig _wrap的错误位置.cxx文件...所以你需要将它移动到“extern C”块:

C ++  -  Java包装器移动到正确的位置

UPDATE: October 15, 2017 更新:2017年10月15日

I'd be remiss if I didn't mention that Android Studio 2.2 onwards has essentially 'native' (no pun) support for the NDK toolchain via Gradle and CMake. 如果我没有提到Android Studio 2.2以后通过Gradle和CMake对NDK工具链提供了基本上“本机”(没有双关语)的支持,那将是我的疏忽。 Now, when you create a new project, just select C++ support and you're good to go. 现在,当您创建一个新项目时,只需选择C ++支持,就可以了。

You'll still need to generate your own JNI layer code, or use the SWIG technique I've mentioned above, but the scaffolding of a C++ in Android project is trivial now. 你仍然需要生成自己的JNI层代码,或者使用我上面提到的SWIG技术,但是现在Android项目中的C ++脚手架是微不足道的。

Changes in the CMakeLists file (which is where you place your C++ source files) will be picked up by Android Studio, and it'll automatically re-compile any associated libraries. 安装工作室将获取CMakeLists文件(您放置C ++源文件的位置)中的更改,它将自动重新编译任何关联的库。

In Google IO 2015, Google announced full NDK integration in Android Studio 1.3. 在Google IO 2015中,Google宣布在Android Studio 1.3中进行完整的NDK集成。

It is now out of preview, and available to everyone: https://developer.android.com/studio/projects/add-native-code.html 它现在已不可用,并且可供所有人使用: https//developer.android.com/studio/projects/add-native-code.html

Old answer: Gradle automatically calls ndk-build if you have a jni directory in your project sources. 旧答案:如果项目源中有jni目录,Gradle会自动调用ndk-build

This is working on Android studio 0.5.9 (canary build). 这适用于Android studio 0.5.9(canary build)。

  1. Download the NDK 下载NDK
  2. Either add ANDROID_NDK_HOME to your environment variables or add ndk.dir=/path/to/ndk to your local.properties in your Android Studio project. ANDROID_NDK_HOME添加到环境变量或将ndk.dir=/path/to/ndk添加ndk.dir=/path/to/ndk到Android Studio项目中的local.properties This allows Android studio to run the ndk automatically. 这允许Android studio自动运行ndk。
  3. Download the latest gradle sample projects to see an example of an ndk project. 下载最新的gradle示例项目以查看ndk项目的示例。 (They're at the bottom of the page). (它们位于页面底部)。 A good sample project is ndkJniLib . 一个很好的示例项目是ndkJniLib
  4. Copy the gradle.build from the NDK sample projects. 从NDK示例项目中复制gradle.build It'll look something like this. 它看起来像这样。 This gradle.build creates a different apk for each architecture. 这个gradle.build为每个架构创建一个不同的apk。 You must select which architecture you want using the build variants pane. 您必须使用build variants窗格选择所需的体系结构。 构建变体窗格

     apply plugin: 'android' dependencies { compile project(':lib') } android { compileSdkVersion 19 buildToolsVersion "19.0.2" // This actual the app version code. Giving ourselves 100,000 values [0, 99999] defaultConfig.versionCode = 123 flavorDimensions "api", "abi" productFlavors { gingerbread { flavorDimension "api" minSdkVersion 10 versionCode = 1 } icecreamSandwich { flavorDimension "api" minSdkVersion 14 versionCode = 2 } x86 { flavorDimension "abi" ndk { abiFilter "x86" } // this is the flavor part of the version code. // It must be higher than the arm one for devices supporting // both, as x86 is preferred. versionCode = 3 } arm { flavorDimension "abi" ndk { abiFilter "armeabi-v7a" } versionCode = 2 } mips { flavorDimension "abi" ndk { abiFilter "mips" } versionCode = 1 } fat { flavorDimension "abi" // fat binary, lowest version code to be // the last option versionCode = 0 } } // make per-variant version code applicationVariants.all { variant -> // get the version code of each flavor def apiVersion = variant.productFlavors.get(0).versionCode def abiVersion = variant.productFlavors.get(1).versionCode // set the composite code variant.mergedFlavor.versionCode = apiVersion * 1000000 + abiVersion * 100000 + defaultConfig.versionCode } } 

Note that this will ignore your Android.mk and Application.mk files. 请注意,这将忽略您的Android.mk和Application.mk文件。 As a workaround, you can tell gradle to disable atuomatic ndk-build call, then specify the directory for ndk sources manually. 作为解决方法,您可以告诉gradle禁用atuomatic ndk-build调用,然后手动指定ndk源的目录。

sourceSets.main {
    jniLibs.srcDir 'src/main/libs' // use the jni .so compiled from the manual ndk-build command
    jni.srcDirs = [] //disable automatic ndk-build call
}

In addition, you'll probably want to call ndk-build in your gradle build script explicitly, because you just disabled the automatic call. 此外,您可能希望明确地在gradle构建脚本中调用ndk-build,因为您刚刚禁用了自动调用。

task ndkBuild(type: Exec) {
   commandLine 'ndk-build', '-C', file('src/main/jni').absolutePath
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn ndkBuild
}

I found "gradle 1.11 com.android.tools.build:gradle:0.9.+" supports pre-build ndk now, you can just put the *.so in the dir src/main/jniLibs. 我发现“gradle 1.11 com.android.tools.build:gradle:0.9.+”现在支持pre-build ndk,你可以将* .so放在dir src / main / jniLibs中。 when building gradle will package the ndk to the right place. 当建立gradle将ndk打包到正确的位置。

here is my project 这是我的项目

Project:
|--src
|--|--main
|--|--|--java
|--|--|--jniLibs
|--|--|--|--armeabi
|--|--|--|--|--.so files
|--libs
|--|--other.jar

As Xavier said, you can put your prebuilts in /src/main/jniLibs/ if you are using gradle 0.7.2+ 正如Xavier所说,如果您使用的是gradle 0.7.2+,可以将预编译放在/ src / main / jniLibs /中

taken from: https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/ctDp9viWaxoJ 取自: https//groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/ctDp9viWaxoJ

As of now (Android Studio v0.8.6) it's quite simple. 截至目前(Android Studio v0.8.6),它非常简单。 Here are the steps to create a "Hello world" type app: 以下是创建“Hello world”类型应用程序的步骤:

  1. Download the Android NDK and put the root folder somewhere sane -- in the same location as the SDK folder, perhaps. 下载Android NDK并将根文件夹放在某处 - 与SDK文件夹位于同一位置。

  2. Add the following to your local.properties file: ndk.dir=<path-to-ndk> 将以下内容添加到local.properties文件中: ndk.dir=<path-to-ndk>

  3. Add the following to your build.gradle file inside of the defaultConfig closure, right after the versionName line: ndk { moduleName="hello-world" } 将以下内容添加到defaultConfig闭包内的build.gradle文件中,紧跟在versionName行之后: ndk { moduleName="hello-world" }

  4. In your app module's main directory, create a new folder called jni . 在app模块的main目录中,创建一个名为jni的新文件夹。

  5. In that folder, create a file called hello-world.c , which you'll see below. 在该文件夹中,创建一个名为hello-world.c的文件,您将在下面看到。

  6. See the example Activity code below for an example of how to call a method (or is it a function?) in hello-world.c . 有关如何在hello-world.c调用方法(或者它是函数?)的示例,请参阅下面的示例Activity代码。


hello-world.c

#include <string.h>
#include <jni.h>

jstring
Java_me_mattlogan_ndktest_MainActivity_stringFromJNI(JNIEnv* env, jobject thiz)
{
    return (*env)->NewStringUTF(env, "Hello world!");
}

MainActivity.java

public class MainActivity extends Activity {

    static {
        System.loadLibrary("hello-world");
    }

    public native String stringFromJNI();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String testString = stringFromJNI();

        TextView mainText = (TextView) findViewById(R.id.main_text);
        mainText.setText(testString);
    }
}

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 20
    buildToolsVersion "20.0.0"

    defaultConfig {
        applicationId "me.mattlogan.ndktest"
        minSdkVersion 15
        targetSdkVersion 20
        versionCode 1
        versionName "1.0"

        ndk {
            moduleName "hello-world"
        }
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

Find the full source code of a very similar app here (minus the NDK). 在这里找到一个非常相似的应用程序的完整源代码(减去NDK)。

If you're on unix the latest version (0.8) adds ndk-build. 如果您使用的是unix,则最新版本(0.8)会添加ndk-build。 Here's how to add it: 以下是添加方法:

android.ndk {
    moduleName "libraw"
}

It expects to find the JNI under 'src/main/jni', otherwise you can define it with: 它希望在'src / main / jni'下找到JNI,否则您可以使用以下命令定义它:

sourceSets.main {
    jni.srcDirs = 'path'
}

As of 28 JAN 2014 with version 0.8 the build is broken on windows, you have to disable the build with: 截至2014年1月28日,版本0.8的版本在Windows上打破,你必须禁用构建:

sourceSets.main {
    jni.srcDirs = [] //disable automatic ndk-build call (currently broken for windows)
}

An elegant workaround is shown in https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/Z5yWAvCh4h4J . https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/Z5yWAvCh4h4J中显示了一种优雅的解决方法。

Basically you create a jar which contains "lib/armeabi/yourlib.so" and then include the jar in the build. 基本上你创建一个包含“lib / armeabi / yourlib.so”的jar,然后在构建中包含jar。

A good answer automating the packaging of readily compiled .so -files is given in another (closed) thread . 另一个(封闭的)线程中给出了一个很好的答案,可以自动编译易于编译的.so文件。 To get that working, I had to change the line: 为了实现这一点,我不得不改变这条线:

from fileTree(dir: 'libs', include: '**/*.so')

into: 成:

from fileTree(dir: 'src/main/libs', include: '**/*.so') 

Without this change the .so files were not found, and the task for packaging them would therefore never run. 没有这个改变,找不到.so文件,因此打包它们的任务永远不会运行。

The answer from @plaisthos broke in the latest gradle version, but there is still a way to do it. @plaisthos的答案打破了最新的gradle版本,但仍有办法实现。 Create a native-libs directory in the root of your project directory and copy all y our libs into this directory. 在项目目录的根目录中创建native-libs目录,并将所有lib复制到此目录中。

Add the following lines to your build.gradle. 将以下行添加到build.gradle中。 Build and be happy. 建立并快乐。

task copyNativeLibs(type: Copy) {
    from(new File(project(':<your project>').getProjectDir(), 'native-libs')) { include '**/*.so' }
    into new File(buildDir, 'native-libs')
}

tasks.withType(Compile) { compileTask -> compileTask.dependsOn copyNativeLibs }

clean.dependsOn 'cleanCopyNativeLibs'

This is the code i use to build using android-ndk from gradle. 这是我用来从gradle使用android-ndk构建的代码。 For this add ndk directory path in gradle.properties ie . 为此,在gradle.properties添加ndk目录路径即。 add ndkdir=/home/user/android-ndk-r9d and put all jni files in a folder native in src/main/ as you can see from code posted below. 添加ndkdir=/home/user/android-ndk-r9d并将所有jni文件放在src/main/中的native文件夹中,如下面的代码所示。 It will create jar with native libs which you can use normally as in System.loadLibrary("libraryname"); 它将创建具有本机库的jar,您可以像在System.loadLibrary("libraryname");那样正常使用它System.loadLibrary("libraryname");

dependencies {
    compile fileTree(dir: "$buildDir/native-libs", include: '*.jar')
}

task ndkBuild(type: Exec) {
    commandLine "$ndkdir/ndk-build", "--directory", "$projectDir/src/main/native", '-j', Runtime.runtime.availableProcessors(),
            "APP_PLATFORM=android-8",
            "APP_BUILD_SCRIPT=$projectDir/src/main/native/Android.mk",
            "NDK_OUT=$buildDir/native/obj",
            "NDK_APP_DST_DIR=$buildDir/native/libs/\$(TARGET_ARCH_ABI)"
}

task nativeLibsToJar(type: Jar, description: 'create a jar with native libs') {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    from fileTree(dir: "$buildDir/native/libs", include: '**/*.so')
    into 'lib/'
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn nativeLibsToJar
}

nativeLibsToJar.dependsOn 'ndkBuild'

I have used the following code to compile native dropbox libraries, I am using Android Studio v1.1. 我使用以下代码编译本机dropbox库,我使用的是Android Studio v1.1。

task nativeLibsToJar(type: Zip) {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    extension 'jar'
    from fileTree(dir: 'src/main/libs', include: '**/*.so')
    into 'lib/'
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn(nativeLibsToJar)
}

I have used ndk.dir=/usr/shareData/android-ndk-r11b // path of ndk 我使用了ndk.dir=/usr/shareData/android-ndk-r11b // ndk.dir=/usr/shareData/android-ndk-r11b路径

in local.properties file in android studio project. 在android studio项目的local.properties文件中。 and add this line : 并添加此行:
android.useDeprecatedNdk=true

in gradle.properties file in android studio project. 在android studio项目的gradle.properties文件中。

More information here: http://tools.android.com/tech-docs/android-ndk-preview 更多信息请访问: http//tools.android.com/tech-docs/android-ndk-preview

To expand on what Naxos said (Thanks Naxos for sending me in the right direction!), I learned quite a bit from the recently released NDK examples and posted an answer in a similar question here. 为了扩展Naxos所说的内容(感谢Naxos向我发送了正确的方向!),我从最近发布的NDK示例中学到了很多,并在此处发布了类似问题的答案。

How to configure NDK with Android Gradle plugin 0.7 如何使用Android Gradle插件0.7配置NDK

This post has full details on linking prebuilt native libraries into your app for the various architectures as well as information on how to add NDK support directly to the build.gradle script. 本文详细介绍了如何将预构建的本机库链接到各种体系结构的应用程序中,以及有关如何将NDK支持直接添加到build.gradle脚本的信息。 For the most part, you shouldn't need to do the work around zip and copy anymore. 在大多数情况下,您不需要再进行zip和复制工作。

configure project in android studio from eclipse: you have to import eclipse ndk project to android studio without exporting to gradle and it works , also you need to add path of ndk in local.properties ,if shows error then add 从eclipse在android studio中配置项目:你必须将eclipse ndk项目导入到android studio而不导出到gradle并且它可以工作,你还需要在local.properties中添加ndk的路径 ,如果显示错误则添加

sourceSets.main {
        jniLibs.srcDir 'src/main/libs' 
        jni.srcDirs = [] //disable automatic ndk-build callenter code here
    }

in build.gradle file then create jni folder and file using terminal and run it will work build.gradle文件中然后使用终端创建jni文件夹和文件并运行它将工作

Here are the steps that I used to get the NDK working in my Android Studio project. 以下是我在Android Studio项目中使用NDK的步骤。 I used this tutorial to help me out https://software.intel.com/en-us/videos/using-the-ndk-with-android-studio 我用这个教程帮我解决了https://software.intel.com/en-us/videos/using-the-ndk-with-android-studio

In order to use NDK you must add a NDK line to local.properties. 要使用NDK,必须将NDK行添加到local.properties。 So under your sdk.dir add 所以根据你的sdk.dir添加

ndk.dir=C\:\\MyPathToMyNDK\ndk

In my apps build.gradle I have the following code 在我的应用程序build.gradle中,我有以下代码

        ndk {
            moduleName "myLib"
            ldLibs "log"
            stl "gnustl_shared"
            cFlags "-std=c++11 -frtti -fexceptions -pthread"
        }

moduleName is the name you want to give your native code. moduleName是您要为本机代码提供的名称。 I believe this is what the shared library will be called. 我相信这就是共享库的名称。 ldLibs allows me to log to LogCat, stl is the stl that you want to import. ldLibs允许我登录到LogCat,stl是你要导入的stl。 There are lots of options, same as the Eclipse NDK. 有很多选项,与Eclipse NDK相同。 ( http://www.kandroid.org/ndk/docs/CPLUSPLUS-SUPPORT.html ) http://www.kandroid.org/ndk/docs/CPLUSPLUS-SUPPORT.html

cFlags are still a certain amount of black magic for me. cFlags对我来说仍然是一定数量的黑魔法。 I have not found a good source for all the options and what they give me. 我没有找到所有选项的好来源以及他们给我的东西。 Search around StackOverflow for anything you need, that is where I found it. 在StackOverflow中搜索您需要的任何内容,这就是我找到它的地方。 I do know that the c++11 allows me to use the new c++ 11 standard. 我知道c ++ 11允许我使用新的c ++ 11标准。

Here is an example of how I log to LogCat from the native code 以下是我如何从本机代码登录LogCat的示例

__android_log_print(ANDROID_LOG_DEBUG, "TestApp", "Adding - String %d has a field name of %s and a value of %s", i, lKeyUTF8.c_str(), lValueUTF8.c_str());

Now that Android Studio is in the stable channel, it is pretty straightforward to get the android-ndk samples running. 既然Android Studio处于稳定的通道中,那么运行android-ndk示例非常简单。 These samples use the ndk experimental plugin and are newer than the ones linked to from the Android NDK online documentation. 这些示例使用的是ndk实验插件 ,比Android NDK在线文档中链接的更新。 Once you know they work you can study the build.gradle, local.properties and gradle-wrapper.properties files and modify your project accordingly. 一旦您知道它们可以工作,您就可以学习build.gradle,local.properties和gradle-wrapper.properties文件并相应地修改您的项目。 Following are the steps to get them working. 以下是让它们工作的步骤。

  1. Go to settings, Appearance & Behavior, System Settings, Android SDK, selected the SDK Tools tab, and check Android NDK version 1.0.0 at the bottom of the list. 转到设置,外观和行为,系统设置,Android SDK,选择SDK工具选项卡,然后检查列表底部的Android NDK版本1.0.0。 This will download the NDK. 这将下载NDK。

  2. Point to the location of the newly downloaded NDK. 指向新下载的NDK的位置。 Note that it will be placed in the sdk/ndk-bundle directory. 请注意,它将放在sdk / ndk-bundle目录中。 Do this by selecting File, Project Structure, SDK Location (on left), and supplying a path under Android NDK location. 通过选择文件,项目结构,SDK位置(左侧),并在Android NDK位置下提供路径来执行此操作。 This will add an ndk entry to local.properties similar to this: 这将向local.properties添加一个ndk条目,类似于:

    Mac/Linux: ndk.dir=/Android/sdk/ndk-bundle Mac / Linux:ndk.dir = / Android / sdk / ndk-bundle
    Windows: ndk.dir=C:\\Android\\sdk\\ndk-bundle Windows:ndk.dir = C:\\ Android \\ sdk \\ ndk-bundle

I have successfully built and deployed all projects in the repository this way, except gles3gni, native-codec and builder. 我已经成功地以这种方式在存储库中构建和部署了所有项目,除了gles3gni,native-codec和builder。 I'm using the following: 我正在使用以下内容:

Android Studio 1.3 build AI-141.2117773 Android Studio 1.3构建AI-141.2117773
android-ndk samples published July 28, 2015 (link above) 2015年7月28日发布的android-ndk样本(上面的链接)
SDK Tools 24.3.3 SDK工具24.3.3
NDK r10e extracted to C:\\Android\\sdk\\ndk-bundle NDK r10e解压缩到C:\\ Android \\ sdk \\ ndk-bundle
Gradle 2.5 Gradle 2.5
Gradle plugin 0.2.0 Gradle插件0.2.0
Windows 8.1 64 bit Windows 8.1 64位

NDK Builds and gradle (basic) NDK构建和gradle(基本)

Generally building with the NDK is as simple as correctly specifying an ndkBuild path to Android.mk or cmake path to CMakeLists.txt. 通常使用NDK构建就像正确指定到Android.mk的ndkBuild路径或到CMakeLists.txt的cmake路径一样简单。 I recommend CMake over the older Android.mk because Android Studio's C/C++ support is based upon CLion and it uses CMake as its project format. 我推荐使用旧版Android.mk上的CMake,因为Android Studio的C / C ++支持基于CLion,它使用CMake作为其项目格式。 This in my experience has tended to make the IDE more responsive on larger projects. 根据我的经验,这往往使IDE在更大的项目上更具响应性。 Everything compiled in your project will be built and copied into the APK automatically. 您项目中编译的所有内容都将自动构建并复制到APK中。

apply plugin: 'com.android.library'

android {
    compileSdkVersion 19
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 19

        ndk {
            abiFilters 'armeabi', 'armeabi-v7a', 'x86'
            // 64-bit support requires an Android API level higher than 19; Namely 21 and higher
            //abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }

        externalNativeBuild {
            cmake {
                arguments '-DANDROID_TOOLCHAIN=clang',
                        '-DANDROID_PLATFORM=android-19',
                        '-DANDROID_STL=gnustl_static',
                        '-DANDROID_ARM_NEON=TRUE'

            }
        }
    }

    externalNativeBuild {
        cmake {
            path 'src/main/jni/CMakeLists.txt'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

Adding prebuilt libraries to the project (advanced) 将预构建的库添加到项目中(高级)

Static libraries (.a) in your NDK build will automatically be included, but prebuilt dynamic libraries (.so) will need to be placed in jniLibs . NDK版本中的静态库(.a)将自动包含在内,但预构建的动态库(.so)将需要放在jniLibs This can be configured using sourceSets , but you should adopt the standard. 这可以使用sourceSets配置,但您应该采用该标准。 You DO NOT NEED any additional commands in build.gradle when including prebuilt libraries. 在包含预构建库时,您build.gradle任何其他命令。

The layout of jniLibs jniLibs的布局

You can find more information about the structure in the Android Gradle Plugin User Guide . 您可以在Android Gradle Plugin用户指南中找到有关该结构的更多信息。

 |--app: |--|--build.gradle |--|--src: |--|--|--main |--|--|--|--java |--|--|--|--jni |--|--|--|--|--CMakeLists.txt |--|--|--|--jniLibs |--|--|--|--|--armeabi |--|--|--|--|--|--.so Files |--|--|--|--|--armeabi-v7a |--|--|--|--|--|--.so Files |--|--|--|--|--x86 |--|--|--|--|--|--.so Files 

You can then validate the resulting APK contains your .so files, typically under build/outputs/apk/ , using unzip -l myApp.apk to list the contents. 然后,您可以使用unzip -l myApp.apk列出内容,验证生成的APK包含您的.so文件,通常位于build/outputs/apk/下。

Building shared libraries 构建共享库

If you're building a shared library in the NDK you do not need to do anything further. 如果您在NDK中构建共享库,则无需进一步操作。 It will be correctly bundled in the APK. 它将被正确捆绑在APK中。

Just add this lines to app build.gradle 只需将此行添加到app build.gradle

dependencies {
    ...
    compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
}

task nativeLibsToJar(type: Zip, description: 'create a jar archive of the native libs') {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    extension 'jar'
    from fileTree(dir: 'libs', include: '**/*.so')
    into 'lib/armeabi/'
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn(nativeLibsToJar)
}

now.I can load the so success! now.I可以加载如此成功!

1.add the .so file to this path 1.将.so文件添加到此路径

Project:

|--src |--|--main |--|--|--java |--|--|--jniLibs |--|--|--|--armeabi |--|--|--|--|--.so files | --src | - | --main | - | - | --java | - | - | --jniLibs | - | - | - | --armeabi | - | - | - | - | - 。so文件

2.add this code to gradle.build 2.将此代码添加到gradle.build

android {
splits {
    abi {
        enable true
        reset()
        include 'x86', 'x86_64', 'arm64-v8a', 'armeabi-v7a', 'armeabi'
        universalApk false
    }
}

} }

3. System.loadLibrary("yousoname"); 3. System.loadLibrary("yousoname");

  1. goodluck for you,it is ok with gradle 1.2.3 goodluck for you,gradle 1.2.3还可以
  1. If your project exported from eclipse,add the codes below in gradle file: 如果您的项目是从eclipse导出的,请在gradle文件中添加以下代码:

     android { sourceSets{ main{ jniLibs.srcDir['libs'] } } } 

2.If you create a project in Android studio: 2.如果您在Android studio中创建项目:

create a folder named jniLibs in src/main/ ,and put your *.so files in the jniLibs folder. 在src / main /中创建一个名为jniLibs的文件夹,并将* .so文件放在jniLibs文件夹中。

And copy code as below in your gradle file : 并在gradle文件中复制以下代码:

android {
    sourceSets{  
       main{  
         jniLibs.srcDir['jniLibs']  
      }  
    }
}

While I believe SJoshi (oracle guy) has the most complete answer, the SWIG project is a special case, interesting and useful one, at that, but not generalized for the majority of projects that have done well with the standard SDK ant based projects + NDK. 虽然我相信SJoshi(oracle guy)有最完整的答案,但是SWIG项目是一个特殊的案例,有趣且有用,但是对于大多数已经完成标准SDK ant项目的项目而言并非一般化+ NDK。 We all would like to be using Android studio now most likely, or want a more CI friendly build toolchain for mobile, which gradle theoretically offers. 我们都希望现在最有可能使用Android工作室,或者想要一个更加CI友好的移动构建工具链,理论上可以提供gradle。

I've posted my approach, borrowed from somewhere (I found this on SO, but posted a gist for the app build.gradle: https://gist.github.com/truedat101/c45ff2b69e91d5c8e9c7962d4b96e841 ). 我已经发布了我的方法,从某个地方借来的(我在SO上找到了这个,但发布了应用build.gradle的一个要点: https ://gist.github.com/truedat101/c45ff2b69e91d5c8e9c7962d4b96e841)。 In a nutshell, I recommend the following: 简而言之,我建议如下:

  • Don't upgrade your project to the latest gradle build 不要将项目升级到最新的gradle构建
  • Use com.android.tools.build:gradle:1.5.0 in your Project root 在项目根目录中使用com.android.tools.build:gradle:1.5.0
  • Use com.android.application in your app project 在app项目中使用com.android.application
  • Make sure gradle.properties has: android.useDeprecatedNdk=true (in case it's complaining) 确保gradle.properties具有:android.useDeprecatedNdk = true(如果它在抱怨)
  • Use the above approach to ensure that your hours and hours of effort creating Android.mk files won't be tossed away. 使用上述方法可确保您创建Android.mk文件的工作时间和工作时间不会被丢弃。 You control which targets arch(s) to build. 您可以控制要构建的目标拱。 And these instructions are kind to Windows users, who should theoretically be able to build on windows without special issues. 这些说明对Windows用户很友好,理论上他们应该能够在没有特殊问题的情况下构建Windows。

Gradle for Android has been a mess in my opinion, much as I like the maven concepts borrowed and the opinionated structure of directories for a project. Gradle for Android在我看来一直很混乱,就像我喜欢借用的maven概念和项目的目录结构一样。 This NDK feature has been "coming soon" for almost 3+ years. 这个NDK功能已经“即将推出”近3年以上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM