我是NDK、gradle和Android Studio(AS)的新手,在将hello-neon(NDK示例)导入AS时遇到了一些问题。我的操作系统是MAC OS X Yosemite。
在local.properties
中设置了ndk.dir
和sdk.dir
,并将android.useDeprecatedNdk=true
写入gradle.properties
之后,我仍然无法制作此程序,因为我在helloneon.c
中找不到cpu-features.h
。
我找了几种方法。唯一有效的方法是添加
sourceSets.main {
jni.srcDirs = []
}
至CCD_ 8。
之后,我们可以制作项目并将其安装在安卓虚拟机上。但是,当我打开应用程序时,它会崩溃。为了找到原因,我发现HelloNeon.java
的public native String stringFromJNI()
无法链接到helloneon.c
的实现。("无法解析相应的Jni函数")
仍然按照stackoverflow提供的说明,我使用ndk构建来构建源代码(需要添加指向cpufeatures的环境变量),并将.so文件添加到该项目中,比如我的项目结构的屏幕截图
这样做(添加.so文件)后,在HelloNeon.java
的stringFromJNI中仍然说"无法解析相应的Jni函数"。但它可以是"制作项目",可以在我的虚拟机上成功运行
我不知道这是否是一个好的解决方案,因为即使可以编译,AS仍然会在HelloNeon.java
报告错误
然后我尝试在build.gradle
中添加以下句子
sourceSets.main {
jniLibs.srcDir 'src/main/jinLibs'
}
它不会改变任何事情。(这些代码可以删除。--通过bullsy)
我还尝试将cpu-features.h
和cpu-features.c
复制到/main/jni,然后我们可以找到cpu-features.h
,但错过了其他文件。
因此,我来到这里寻求帮助。你能帮我们指出我们犯的错误以及解决错误的正确方法吗?尽管这对该领域的专家来说是一个幼稚的问题,但我真的很感激你作为一个新人在该领域的帮助。
非常感谢!
这是我的build.gradle
(模块:应用程序):
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.example.neon"
minSdkVersion 4
targetSdkVersion 4
ndk {
moduleName "helloneon"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
sourceSets.main {
jni.srcDirs = []
}
sourceSets.main {
jniLibs.srcDir 'src/main/jinLibs' // <-- Set your folder here!
}
}
这是我的另一个build.gradle
(项目:你好霓虹灯):
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
}
}
allprojects {
repositories {
jcenter()
}
}
这是我的settings.gradle
:
include ':app'
include ':cpufeatures'
我的Android Studio版本是1.5.1
我的ndk版本(./ndk-build -version
)是GNU Make 3.81
再次感谢。
更新
谢谢你。我在build.gradle
中添加了以下代码:
task ndkBuild(type: Exec) {
commandLine 'ndk-build', '-C', commandLine 'ndk-build', '-C', file('/Users/zhu/AndroidStudioProjects/hello-neon/app/src/main')
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
并在ndk-build
:中获取了"制作项目"时的一些错误信息
Information:Gradle tasks [:app:generateDebugSources, :app:generateDebugAndroidTestSources, :app:compileDebugSources, :app:compileDebugAndroidTestSources]
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:preDebugAndroidTestBuild UP-TO-DATE
:app:prepareDebugAndroidTestDependencies
:app:compileDebugAndroidTestAidl UP-TO-DATE
:app:processDebugAndroidTestManifest UP-TO-DATE
:app:compileDebugAndroidTestRenderscript UP-TO-DATE
:app:generateDebugAndroidTestBuildConfig UP-TO-DATE
:app:generateDebugAndroidTestAssets UP-TO-DATE
:app:mergeDebugAndroidTestAssets UP-TO-DATE
:app:generateDebugAndroidTestResValues UP-TO-DATE
:app:generateDebugAndroidTestResources UP-TO-DATE
:app:mergeDebugAndroidTestResources UP-TO-DATE
:app:processDebugAndroidTestResources UP-TO-DATE
:app:generateDebugAndroidTestSources UP-TO-DATE
:app:ndkBuild
make: *** /Users/zhu/AndroidStudioProjects/hello-neon/app/main: No such file or directory. Stop.
Error:Execution failed for task ':app:ndkBuild'.
> Process 'command 'ndk-build'' finished with non-zero exit value 2
Information:BUILD FAILED
然后我使用/Applications/Android Studio.app/Contents/MacOS/studio
启动AS,这样AS就可以从bash中读取环境变量,这些代码就可以工作了!
但是,这个.so文件将存储在"/Users/zhu/AndroidStudioProjects/hello-neon/app/src/main/libs"中,并且这些.so文件无法直接加载(看起来项目只会在jniLibs/中加载.so文件)。
因此,我应该添加吗
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
}
如果没有,我该怎么办?
删除此代码:
sourceSets.main {
jniLibs.srcDir 'src/main/jinLibs' // <-- Set your folder here!
}
因为您使用的是Android.mk,所以将jniLibs.srcDir
设置为空是正确的。这告诉构建系统不要覆盖你的Android.mk文件。为了正确构建,您需要从build.gradle调用ndk-build
,并将其指向jni目录。设置对ndk-build
的调用可能如下所示:
// call regular ndk-build(.cmd) script from app directory
task ndkBuild(type: Exec) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath
} else {
commandLine 'ndk-build', '-C', file('src/main').absolutePath
}
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
这些示例摘自ph0b关于使用旧版本NDK的优秀教程。如果你有兴趣在未来的某个时候,当你稍微舒服一点的时候,尝试实验性的NDK支持,ph0b也发布了一些很棒的东西。