我是很新的这整个gradle这个和Android Studio的支持。 我已成功地将我的Android项目使用导出选项摇篮。
但我要寻找一些文档或起点如何整合NDK建设成为gradle这个生成过程。
如果可能的话我还需要某种形式的舞台“后,”那份编译二进制文件(.so文件),以该资产目录。
我是很新的这整个gradle这个和Android Studio的支持。 我已成功地将我的Android项目使用导出选项摇篮。
但我要寻找一些文档或起点如何整合NDK建设成为gradle这个生成过程。
如果可能的话我还需要某种形式的舞台“后,”那份编译二进制文件(.so文件),以该资产目录。
我们已经在1.3发布了整合的第一个版本的预览: http://tools.android.com/tech-docs/android-ndk-preview
整合将留下一个预览1.3成为最终甚至之后。 当前没有ETA何时这将是最后的(如2015年7月10日的)。
这里更多信息: http://tools.android.com/tech-docs/android-ndk-preview
UPDATE:Android的工作室NDK的支持是现在出来: http://tools.android.com/tech-docs/android-ndk-preview
对于脚本以下gradle这个解决方案应该工作的基础上:
我用我的构建脚本,并添加到我的文件(似乎对工作0.8+
):这似乎是等同于下面的解决方案(但在gradle这个文件看起来更好):
android {
sourceSets {
main {
jniLibs.srcDirs = ['native-libs']
jni.srcDirs = [] //disable automatic ndk-build
}
}
}
构建不幸的是,如果该目录不存在或不包含不会失败.so
文件。
随着Android Studio中的1.0更新中,NDK工具链支持了很大的改进( 注意:请在文章底部阅读我的更新,看看使用新的实验摇篮插件和Android工作室1.5)。
安卓Studio和NDK集成不够好,这样你只需要创建你的模块的build.gradle的NDK {}块,并设置源文件添加到(模块)/ src目录/主/ JNI目录 - 和你完成了!
在命令行中没有更多的NDK-建设。
我已经写了有关它的一切在我的博客张贴在这里: http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/
要点是:
有你需要知道这里两件事情。 默认情况下,如果你有需要加载到Android应用程序的外部库,它们是在(模块)中寻找默认/ src目录/主/ jniLibs。 您可以通过在你的模块的build.gradle使用设置sourceSets.main.jniLibs.srcDirs改变这一点。 你需要与您指定的每个架构库子目录(如X86,ARM,MIPS,arm64-V8A,等...)
你想要的代码在默认情况下被编译由NDK工具链将位于(模块)/ src目录/主/ JNI,同样上面,你可以通过在模块的build.gradle设置sourceSets.main.jni.srcDirs改变
并把这个变成你的模块的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
}
这是编译你的C ++代码,从那里你需要加载它,并创建包装的过程 - 但是从你的问题来看,你已经知道该怎么做了这一切,所以我不会再哈希。
此外,我放置在这个例子的Github上回购在这里: http://github.com/sureshjoshi/android-ndk-swig-example
当Android的工作室1.3出来的时候,应该有通过JetBrains的克利翁插件C ++更好的支持。 我目前的假设,这将允许Java和C ++开发在Android Studio中下; 然而,我认为我们仍然需要使用NDK摇篮的部分我已经如上所述。 此外,我认为仍然会有编写Java需要< - > C ++封装文件,除非克利翁会自动完成这些。
我已经更新我的博客和GitHub库(在开发分支)采用Android 1.5工作室与最新的实验摇篮插件(0.6.0-素α3)。
http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/ http://github.com/sureshjoshi/android-ndk-swig-example
该摇篮建立NDK的部分现在看起来是这样的:
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
}
此外,相当赫然,Android的Studio有自动完成对C ++ - 生成的Java使用“天然”关键字包装:
然而,这并不完全乐观...如果你使用痛饮包库自动生成代码,然后尝试使用native关键字自动生成,它将把代码中错误的地方在你痛饮_wrap .CXX文件......所以,你需要将它移动到“外部C”块:
我是失职,如果我没有提到的Android Studio 2.2中开始基本具有“天然”(没有双关语),用于通过摇篮和C进行NDK工具链支持。 现在,当你创建一个新的项目,只需选择C ++的支持,你是好去。
你仍然需要生成自己的JNI层的代码,或者用我上面提到的SWIG技术,但在Android项目一个C ++的脚手架现在是微不足道的。
在CMakeLists文件的变化(这是你把你的C ++源文件)将搭载Android Studio中拾起,它会自动重新编译任何相关的库。
现在出来的预览,并提供给大家: https://developer.android.com/studio/projects/add-native-code.html
ndk-build
,如果你有一个jni
在项目源目录。 这是工作在Android工作室0.5.9(金丝雀版本)。
ANDROID_NDK_HOME
到你的环境变量或添加ndk.dir=/path/to/ndk
您local.properties
在你的Android Studio项目。 这使得Android的工作室自动运行NDK。 ndkJniLib
。 副本gradle.build
从NDK样本项目。 它会是这个样子。 这gradle.build
会为每个架构不同的APK。 你必须选择要使用该架构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 } }
请注意,这会忽略你的Android.mk和Application.mk文件。 作为一种变通方法,你可以告诉gradle这个禁用atuomatic NDK建造通话,然后手动指定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
}
此外,你可能会想打电话给你的gradle这个构建脚本NDK,建立明确的,因为你禁用了自动呼叫。
task ndkBuild(type: Exec) {
commandLine 'ndk-build', '-C', file('src/main/jni').absolutePath
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
我发现“gradle这个1.11 com.android.tools.build:gradle:0.9.+”现在支持预构建NDK,你可以把*。所以在目录的src / main / jniLibs。 当的gradle建设将打包NDK到合适的位置。
这里是我的项目
Project: |--src |--|--main |--|--|--java |--|--|--jniLibs |--|--|--|--armeabi |--|--|--|--|--.so files |--libs |--|--other.jar
正如泽维尔说,你可以把你的prebuilts在/ src目录/主/ jniLibs /如果你正在使用gradle这个0.7.2+
:取自https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/ctDp9viWaxoJ
截至目前(Android Studio中v0.8.6),这是相当简单的。 这里是创建一个“Hello World”类型的应用程序的步骤:
下载Android NDK,把根文件夹中的某处理智 - 在相同的位置SDK文件夹,也许吧。
以下内容添加到您的local.properties
文件: ndk.dir=<path-to-ndk>
将下列内容添加到里面你的build.gradle文件defaultConfig
关闭,在之后versionName
行: ndk { moduleName="hello-world" }
在您的应用程序模块的main
目录下创建一个名为新文件夹jni
。
在该文件夹,创建一个名为hello-world.c
,你会看到如下。
参见示例Activity
以下代码的如何调用的方法的示例(或者是一个功能?)在hello-world.c
。
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'])
}
在这里找到一个非常类似的应用程序的完整源代码(减去NDK)。
如果你是UNIX上的最新版本(0.8)将NDK建造。 以下是如何添加它:
android.ndk {
moduleName "libraw"
}
它期望找到JNI下“的src / main / JNI”,否则,你可以定义它:
sourceSets.main {
jni.srcDirs = 'path'
}
随着2014年1月28日的0.8版本构建在Windows坏了,你有禁用编译:
sourceSets.main {
jni.srcDirs = [] //disable automatic ndk-build call (currently broken for windows)
}
优雅的解决方法示于https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/Z5yWAvCh4h4J 。
基本上你创建一个包含一个jar“的lib / armeabi / yourlib.so”,然后包括构建罐子。
一个较好的答案自动化的编译容易包装.so
-files中给出另一个(关闭)线程 。 为了得到那个工作,我不得不改变线路:
from fileTree(dir: 'libs', include: '**/*.so')
成:
from fileTree(dir: 'src/main/libs', include: '**/*.so')
没有这个变化.so
文件没有找到,因此用于包装他们的任务将永远不会运行。
从@plaisthos答案在最新版本的Gradle爆发,但仍有办法做到这一点。 创建native-libs
在你的项目目录的根目录,所有的Y我们的库复制到这个目录。
添加以下行到你的build.gradle。 建立和快乐。
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'
这是我使用使用Android的NDK的gradle从构建代码。 对于这种添加在NDK目录路径gradle.properties
即。 添加ndkdir=/home/user/android-ndk-r9d
,并把所有JNI文件夹native
中src/main/
因为你可以从下面贴出代码看看。 这将创建一个本地库罐子,你可以正常使用中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'
我用下面的代码编译本地Dropbox的图书馆,我使用过Android Studio 1.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)
}
我已经使用ndk.dir=/usr/shareData/android-ndk-r11b
// NDK的路径
在local.properties文件中的Android Studio项目。 并加入这一行:
android.useDeprecatedNdk=true
在gradle.properties文件中的Android Studio项目。
这里更多信息: http://tools.android.com/tech-docs/android-ndk-preview
为了扩大在什么说拿索斯(Naxos的感谢送我在正确的方向!),我学会从最近发布的NDK的例子相当多,在这里张贴了类似的问题的答案。
如何与Android摇篮插件0.7配置NDK
这篇文章对链接预构建的本机库为您的应用程序的各种架构以及信息如何直接添加NDK支持到的build.gradle脚本全部细节。 在大多数情况下,你不应该需要做的工作都是围绕压缩和复制了。
下面是我用来获取NDK在我的Android Studio项目的工作步骤。 我用这个教程来帮助我https://software.intel.com/en-us/videos/using-the-ndk-with-android-studio
为了使用NDK必须将NDK行添加到local.properties。 所以,你的sdk.dir下添加
ndk.dir=C\:\\MyPathToMyNDK\ndk
在我的应用程序的build.gradle我有以下代码
ndk {
moduleName "myLib"
ldLibs "log"
stl "gnustl_shared"
cFlags "-std=c++11 -frtti -fexceptions -pthread"
}
MODULENAME是你想给你的本机代码的名称。 我相信这是共享库将被调用。 LDLIBS让我登录到logcat中,STL是要导入的STL。 有很多的选择,相同的Eclipse NDK。 ( http://www.kandroid.org/ndk/docs/CPLUSPLUS-SUPPORT.html )
CFLAGS尚有一定量的黑魔法我。 我还没有发现对所有的选项,他们给我什么好来源。 各地StackOverflow的搜索您需要什么,这是我发现了它。 我不知道C ++ 11允许我使用新的C ++ 11个标准。
下面是我如何记录从本地代码到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());
从日食在Android Studio中配置项目:你必须导入Eclipse项目NDK到Android工作室没有出口到gradle这个和它的作品,你也需要添加local.properties NDK的路径,如果显示错误再加入
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
jni.srcDirs = [] //disable automatic ndk-build callenter code here
}
在文件的build.gradle然后创建JNI文件夹和文件使用终端,运行它会工作
现在,Android的工作室是在稳定的渠道,这是非常简单的获得Android的NDK样本运行。 这些样品使用NDK实验插件 ,比从Android NDK在线文档链接到那些较新的。 一旦你知道他们的工作,你可以研究的build.gradle,local.properties和gradle-wrapper.properties文件,并相应修改您的项目。 以下是让他们的工作步骤。
进入设置,外观和行为,系统设置,Android SDK中,所选择的SDK工具选项卡,然后在列表的底部查看Android NDK版本1.0.0。 这将下载的NDK。
指向新下载的NDK的位置。 请注意,它将被放置在SDK / NDK-bundle目录。 通过选择(上左)文件,项目结构,SDK位置,并提供下的Android NDK位置的路径执行此操作。 这将添加一个NDK条目与此类似local.properties:
Mac / Linux中ndk.dir = /安卓/ SDK / NDK束
Windows系统:ndk.dir = C:\ Android的\ SDK \ NDK束
我已经成功地构建和部署存储库中的所有项目这种方式,除了gles3gni,原生编解码器和建设者。 我使用的是以下情况:
Android Studio中建立1.3 AI-141.2117773
公布的7月28日的Android-NDK样本,2015(以上链接)
SDK工具24.3.3
NDK r10e提取到C:\的Android \ SDK \ NDK束
2.5摇篮
摇篮插件0.2.0
Windows 8.1中的64位
通常与建筑NDK很简单,只要正确地指定ndkBuild路径的Android.mk或cmake的路径的CMakeLists.txt。 我建议CMake的比旧的Android.mk由于Android Studio的C / C ++的支持是基于克利翁和它使用的CMake作为其项目的格式。 这在我的经验往往使IDE上的较大的项目更加敏感。 在您的项目编译一切都将建成并自动复制到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'])
}
在你的NDK生成静态库(.a)中会自动被包括在内,但预构建的动态库(.so)将需要被放置在jniLibs
。 这可以通过以下方式配置sourceSets
,但你应该采取的标准。 你没有需要任何额外的命令build.gradle
包括预建库时。
jniLibs
你可以找到有关的结构的更多信息Android的摇篮Plugin用户指南 。
|--app: |--|--build.gradle |--|--src: |--|--|--main |--|--|--|--java |--|--|--|--jni |--|--|--|--|--CMakeLists.txt |--|--|--|--jniLibs |--|--|--|--|--armeabi |--|--|--|--|--|--.so Files |--|--|--|--|--armeabi-v7a |--|--|--|--|--|--.so Files |--|--|--|--|--x86 |--|--|--|--|--|--.so Files
然后,您可以验证所产生的APK包含您的.so文件,通常在build/outputs/apk/
使用unzip -l myApp.apk
列出的内容。
如果你在NDK构建一个共享库,你不需要做其他事情。 它会在APK正确地捆绑在一起。
只需添加这行应用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可以加载如此成功!
该.so文件1.增加这个路径
Project:
| --src | - | - 主| - | - | --java | - | - | --jniLibs | - | - | - | --armeabi | - | - | - | - | - 所以文件
2.加这个代码gradle.build
android {
splits {
abi {
enable true
reset()
include 'x86', 'x86_64', 'arm64-v8a', 'armeabi-v7a', 'armeabi'
universalApk false
}
}
}
3. System.loadLibrary("yousoname");
如果您的项目在Eclipse中导出,下面添加在gradle这个文件中的代码:
android { sourceSets{ main{ jniLibs.srcDir['libs'] } } }
2.如果您创建Android Studio中的一个项目:
在的src / main /创建一个文件夹命名jniLibs,并把你的* .so文件的文件夹jniLibs。
而在你的gradle这个文件,如下复制代码:
android {
sourceSets{
main{
jniLibs.srcDir['jniLibs']
}
}
}
虽然我相信SJoshi(甲骨文家伙)拥有最完整的答案,该SWIG项目是一个特例,有趣和有用的,在这一点,但不是普遍适用于具有标准的SDK蚂蚁基础的项目做得不好多数项目+ NDK。 我们都希望是现在使用的是Android工作室最有可能的,或者想为移动更CI友好构建工具链,其理论上摇篮提供。
我已为我的做法,从某处借来的(我SO发现这个,但贴了依据该应用的build.gradle: https://gist.github.com/truedat101/c45ff2b69e91d5c8e9c7962d4b96e841 )。 概括地说,我提出以下建议:
摇篮的Android已经在我看来乱七八糟的,尽管我非常喜欢借用行家的概念和目录的某个项目的自以为是的结构。 这个NDK功能已被“即将推出”了近3年。