I am new to NDK, gradle, and Android Studio (AS) and meet some problem while importing hello-neon (ndk samples) to AS. My operating system is MAC OS X Yosemite.
After seting ndk.dir
and sdk.dir
in local.properties
and write android.useDeprecatedNdk=true
to gradle.properties
, I still cannot make this program because I cannot find the cpu-features.h
in helloneon.c
.
I have searched for several methods. The only valid method is to add
sourceSets.main {
jni.srcDirs = []
}
to build.gradle
.
After that, we can Make Project and install it on Android VM. However, the app will crash when I open it. To find the reason, I found that public native String stringFromJNI()
at HelloNeon.java
cannot be linked to its implementation at helloneon.c
. ("cannot resolve corresponding Jni functions")
Still following the instruction provided at stackoverflow, I use ndk-build to build the source code (need to add environment variable pointing to cpufeatures) and add .so files to this project, like screen shot of the structure of my project
After doing so (adding .so files), it is still said "cannot resolve corresponding Jni functions" at stringFromJNI in HelloNeon.java
. But it can be "Make Project" and can be successfully run on my VM!
I don't know whether it is a good solution because AS still report errors at HelloNeon.java
even it can be compile.
Then I try add following sentences to build.gradle
sourceSets.main {
jniLibs.srcDir 'src/main/jinLibs'
}
It does not change any thing. (these code can be delete. --by bullsy)
I also try to copy cpu-features.h
and cpu-features.c
to /main/jni , then we can find the cpu-features.h
but miss other files.
As a result, I come here to find some help. Can you help point out the mistakes we have made and the correct way to solve it? Although this is a naive problem for experts to this area, I really appreciate your help as a new man to this area.
Thank you very much!
This is my build.gradle
(Module: app) :
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!
}
}
This is my another build.gradle
(Project: hello-neon) :
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
}
}
allprojects {
repositories {
jcenter()
}
}
This is my settings.gradle
:
include ':app'
include ':cpufeatures'
My Android Studio version is 1.5.1
My ndk version (./ndk-build -version
) is GNU Make 3.81
Thanks again.
UPDATE
Thank you bullsy. I added following code in my 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
}
And got some error information when "Make Project" in 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
Then I use /Applications/Android\ Studio.app/Contents/MacOS/studio
to start the AS so that AS can read environment variable from bash, these code works!
However, this .so files will be store in "/Users/zhu/AndroidStudioProjects/hello-neon/app/src/main/libs" and these .so file cannot be loaded directly (It seems that the project will only load the .so file in jniLibs/).
As a result, should I add
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
}
If not, what should I do?
答案 0 :(得分:0)
Remove this code:
sourceSets.main {
jniLibs.srcDir 'src/main/jinLibs' // <-- Set your folder here!
}
Because you're using Android.mk, setting jniLibs.srcDir
to empty is correct. This tells the build system not to override your Android.mk file. In order to build properly, you'll need to call ndk-build
from your build.gradle and point it to your jni directory. Setting up the call to ndk-build
might look like this:
// 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
}
These examples are pulled from ph0b's excellent tutorial on working with the older version of the NDK. If you are interested in trying the experimental NDK support at some point in the future when you're a little more comfortable, ph0b has posted some great stuff on that too.