There are two things in my project.
I am creating a static library using ndk-build
Link that Static library to the existing application in Android Studio.
Referred many questions and tried many replies. But none of them works for me.
Here are my doubts,
Where actually should the static libraries placed..?
How to specify the Gradle build system that I am linking static library..?
Please help me with required steps to follow.
Finally I found the answer.
Modify the build.gradle file of the application... as below
android.ndk {
moduleName = "AEC"
ldLibs += ["android", "OpenSLES", "log"]
ldFlags += "/home/lone/AndroidStudioProjects/AcousticEchoCanceller/app/src/main/jni/prebuilt/libToneDetect.a"
ldFlags += "/home/lone/AndroidStudioProjects/AcousticEchoCanceller/app/src/main/jni/prebuilt/libAec.a"
CFlags += ['-std=c99']
}
Note: This works only if library and architecture are same. And the apk is building for only 1 Platform
The gradle-experimental 0.2.0 is pretty old for now. I have a solution for 0.7.2.
put this OUTSIDE of the Android{}
repositories {
libs(PrebuiltLibraries) {
yourlib {
headers.srcDir "src/main/jni/prebuilts/include"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("src/main/jni/prebuilts/${targetPlatform.getName()}/libyourlib.so")
}
}
}
}
and this code INSIDE the Android{}
sources {
main {
jni {
dependencies {
library "yourlib" linkage "shared"
}
}
}
}
the code come from:Xavier Hallade post
Hello-libs is the one that might be helpful too: it builds 2 libs and use them in the app. The building libs and using libs could be de-coupled; for usage, look at the app/build.gradle
the sample are for shared lib; follow the comment above gperf for static lib in that build.gradle [do not put static lib into jniLibs folder, no need], it will work.
CMake + android studio is similar and simpler [they are in master-cmake branch]
Folder structure is relatively important when referencing a static library, I'm going to indicate the structure of mine, obviously it is going to be slightly different for you but hopefully this clears things up a bit. Firstly:
in my (C:) Drive I have a folder called Projects which is a home to all my Android studio projects, in this folder I have my Library, along with the root direc of the App I'm working on (Which uses the library)
The next step would be to open the project you want to use the library in and include these few lines of code.
Expand "Gradle Scripts" and open 'build.gradle(module:app)' and under dependencies add this - compile project(path: ":library")
Next open 'settings.gradle(Project Settings)' and you should see this - include ':app'
Edit the above line to read include ':app', ':library'
and on the line below add this - 'project(":library").projectDir = new File("../(yourlibraryfoldernamehere)/library")'
That SHOULD do the trick, hopefully this helps, if anything is unclear give me a shout and I'll try assist or explain better! Good luck!
Background
In the past, I've made a nice Android library (link here) that allows the developers to contain a bitmap within C/C++ world, play with it, and later convert it back to Java's world.
The problem
Now that I try to import it, I fail to do so on both Eclipse and Android-Studio.
For Android-Studio, I can understand, since it doesn't really support it well yet, but for Eclipse, I've done it many times and it worked fine. I've even made a tutorial based on the problems I've collected over time.
No matter what I do, this is what I get:
A lot of errors in the form of "Type 'X' could not be resolved" .
This also leads to failure in creating the files the sample needs in order to run.
On Android Studio, I get this error:
System Info
Windows 8.1 64bit, Eclipse 4.4.1, ADT 23.0.4.1468518, NDK r10d 64bit
The question
How do I fix it?
What is wrong with my library?
Also, what should I do in order to allow Android Studio users import it?
What is wrong with my library?
I don't think anything is wrong with your library. I believe this is a bug in ADT under Eclipse. See these AOSP bugs:
Issue 33788: [ADT 20] Indexer support regression
Issue 97023: Eclipse/ADT plugin cannot locate symbols for r10d NDK
How do I fix it?
Well, there are lots of workarounds offered in Issue 33788: [ADT 20] Indexer support regression. Some of them are from AOSP and some of them are from regular users.
what should I do in order to allow Android Studio users import it?
Sorry, I can't help here because I don't use Android Studio. I know Android Studio ignores Application.mk and Android.mk, so you might need to add the paths through gradle.build (I think that's what its called).
(It appears the ADT plugin under Eclipse builds paths by parsing Application.mk and Android.mk).
As you know Google announced the new update of Android studio 1.3 RC3, and finally we get C++ support. I configure my app this way and everything working just fine.
Fallow this steps...
Run Android Studio 1.3 RC3 and click Import Project (Eclipse ADT, Gradle, etc.)
See this and this to configure your app.
In project structure (cmd + ; in Mac OS) set Gradle version to 1 and Android Plugin Version leave blank
Then configure you app.gradle file
android.ndk
{
moduleName = "MY_MODULE_NAME"
// this is your additional include files,
// do this if you have subfolder inside of JNI folder
cppFlags += "-I${file("src/main/jni/myFolder/Sources")}".toString()
cppFlags += "-I${file("src/main/jni/myFolder/Sources/Helper")}".toString()
cppFlags += "-I${file("src/main/jni/myFolder/Sources/Image")}".toString()
cppFlags += "-I${file("src/main/jni/myFolder/Sources/Utils")}".toString()
// add c++ 11 support
cppFlags += "-std=c++11"
// your libs
ldLibs += ["log", "jnigraphics"]
stl = "gnustl_static"
}
if you want to use for example cpufeatures , you must add it to your JNI folder. Then in app.gradle file specify path to it in this way .
cppFlags += "-I${file("src/main/jni/cpufeatures")}".toString()
My app.gradle file
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 21
buildToolsVersion = "22.0.1"
defaultConfig.with {
applicationId = "com.example.testapp"
minSdkVersion.apiLevel = 17
targetSdkVersion.apiLevel = 22
}
}
android.ndk {
moduleName = "MY_MODULE_NAME"
// this is your additional include files,
// do this if you have subfolder inside of JNI folder
cppFlags += "-I${file("src/main/jni/myFolder/Sources")}".toString()
cppFlags += "-I${file("src/main/jni/myFolder/Sources/Helper")}".toString()
cppFlags += "-I${file("src/main/jni/myFolder/Sources/Image")}".toString()
cppFlags += "-I${file("src/main/jni/myFolder/Sources/Utils")}".toString()
// add c++ 11 support
cppFlags += "-std=c++11"
// your libs
ldLibs += ["log", "jnigraphics"]
stl = "gnustl_static"
}
// jni is the default dir; config this if yours is in different directory
android.sources {
main {
jni {
source {
srcDirs 'src/main/jni'
}
}
}
}
android.buildTypes {
release {
isMinifyEnabled = false
proguardFiles += file('proguard-rules.txt')
}
}
android.productFlavors {
create ("arm7") {
ndk.abiFilters += "armeabi-v7a"
}
create ("arm8") {
ndk.abiFilters += "arm64-v8a"
}
create ("x86-32") {
ndk.abiFilters += "x86"
}
// for detailed abiFilter descriptions, refer to "Supported ABIs" #
// https://developer.android.com/ndk/guides/abis.html#sa
// build one including all productFlavors
create("fat")
}
}
My project gradle file
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.1.0'
}
}
allprojects {
repositories {
jcenter()
}
}
My gradle-wrapper.properties file
#Mon Jul 20 16:12:41 AMT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-rc-1-all.zip
P.S my reputation is not allowing me to post images, sorry
I am very new to this whole gradle and Android Studio support. I have managed to convert my android project to gradle using the export option.
But I am looking for some documentation or start point how to integrate the NDK build into the gradle build process.
If possible I also need some sort of "after" stage that copies the build binaries (.so files) to the asset directory.
We have released a first version of the integration as a preview in 1.3: http://tools.android.com/tech-docs/android-ndk-preview
The integration will stay a preview even after 1.3 becomes final. No current ETA as to when it'll be final (as of 2015/07/10).
More information here: 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
For building with a script the gradle solution below should work:
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):
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.
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 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!
No more ndk-build from the command line.
I've written all about it in my blog post here: 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. You can change this by using setting sourceSets.main.jniLibs.srcDirs in your module’s build.gradle. You’ll need a subdirectory with libraries for each architecture you’re targeting (e.g. x86, arm, mips, arm64-v8a, etc…)
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
and put this into your module's 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.
Also, I've placed a Github repo of this example here: http://github.com/sureshjoshi/android-ndk-swig-example
UPDATE: June 14, 2015
When Android Studio 1.3 comes out, there should be better support for C++ through the JetBrains CLion plugin. I'm currently under the assumption that this will allow Java and C++ development from within Android Studio; however I think we'll still need to use the Gradle NDK section as I've stated above. Additionally, I think there will still be the need to write Java<->C++ wrapper files, unless CLion will do those automatically.
UPDATE: January 5, 2016
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).
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:
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:
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:
UPDATE: October 15, 2017
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. Now, when you create a new project, just select C++ support and you're good to go.
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.
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.
In Google IO 2015, Google announced full NDK integration in Android Studio 1.3.
It is now out of preview, and available to everyone: 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.
This is working on Android studio 0.5.9 (canary build).
Download the NDK
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. This allows Android studio to run the ndk automatically.
Download the latest gradle sample projects to see an example of an ndk project. (They're at the bottom of the page). A good sample project is ndkJniLib.
Copy the gradle.build from the NDK sample projects. It'll look something like this. This gradle.build creates a different apk for each architecture. You must select which architecture you want using the build variants pane.
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. As a workaround, you can tell gradle to disable atuomatic ndk-build call, then specify the directory for ndk sources manually.
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.
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.
when building gradle will package the ndk to the right place.
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+
taken from: https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/ctDp9viWaxoJ
As of now (Android Studio v0.8.6) it's quite simple. Here are the steps to create a "Hello world" type app:
Download the Android NDK and put the root folder somewhere sane -- in the same location as the SDK folder, perhaps.
Add the following to your local.properties file:
ndk.dir=<path-to-ndk>
Add the following to your build.gradle file inside of the defaultConfig closure, right after the versionName line: ndk { moduleName="hello-world" }
In your app module's main directory, create a new folder called jni.
In that folder, create a file called hello-world.c, which you'll see below.
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
#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).
If you're on unix the latest version (0.8) adds 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:
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:
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.
Basically you create a jar which contains "lib/armeabi/yourlib.so" and then include the jar in the build.
A good answer automating the packaging of readily compiled .so-files is given in another (closed) thread. 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.
The answer from #plaisthos broke in the latest gradle version, but there is still a way to do it.
Create a native-libs directory in the root of your project directory and copy all y our libs into this directory.
Add the following lines to your 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. For this add ndk directory path in gradle.properties ie . 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. It will create jar with native libs which you can use normally as in 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.
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 in local.properties file in android studio project. and
add this line : android.useDeprecatedNdk=true in gradle.properties file in android studio project.
More information here: 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.
How to configure NDK with Android Gradle plugin 0.7
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. For the most part, you shouldn't need to do the work around zip and copy anymore.
Here are the steps that I used to get the NDK working in my Android Studio project.
I used this tutorial to help me out
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. So under your sdk.dir add
ndk.dir=C\:\\MyPathToMyNDK\ndk
In my apps build.gradle I have the following code
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. 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. There are lots of options, same as the Eclipse NDK. (http://www.kandroid.org/ndk/docs/CPLUSPLUS-SUPPORT.html)
cFlags are still a certain amount of black magic for me. 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. I do know that the c++11 allows me to use the new c++ 11 standard.
Here is an example of how I log to LogCat from the native code
__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());
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
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
Now that Android Studio is in the stable channel, it is pretty straightforward to get the android-ndk samples running. These samples use the ndk experimental plugin and are newer than the ones linked to from the Android NDK online documentation. Once you know they work you can study the build.gradle, local.properties and gradle-wrapper.properties files and modify your project accordingly. Following are the steps to get them working.
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. This will download the NDK.
Point to the location of the newly downloaded NDK. Note that it will be placed in the sdk/ndk-bundle directory. Do this by selecting File, Project Structure, SDK Location (on left), and supplying a path under Android NDK location. This will add an ndk entry to local.properties similar to this:
Mac/Linux: ndk.dir=/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. I'm using the following:
Android Studio 1.3 build AI-141.2117773
android-ndk samples published July 28, 2015 (link above)
SDK Tools 24.3.3
NDK r10e extracted to C:\Android\sdk\ndk-bundle
Gradle 2.5
Gradle plugin 0.2.0
Windows 8.1 64 bit
NDK Builds and gradle (basic)
Generally building with the NDK is as simple as correctly specifying an ndkBuild path to Android.mk or cmake path to CMakeLists.txt. 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. This in my experience has tended to make the IDE more responsive on larger projects. Everything compiled in your project will be built and copied into the APK automatically.
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. This can be configured using sourceSets, but you should adopt the standard. You DO NOT NEED any additional commands in build.gradle when including prebuilt libraries.
The layout of jniLibs
You can find more information about the structure in the Android Gradle Plugin User Guide.
|--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.
Building shared libraries
If you're building a shared library in the NDK you do not need to do anything further. It will be correctly bundled in the APK.
Just add this lines to 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!
1.add the .so file to this path
Project:
|--src
|--|--main
|--|--|--java
|--|--|--jniLibs
|--|--|--|--armeabi
|--|--|--|--|--.so files
2.add this code to gradle.build
android {
splits {
abi {
enable true
reset()
include 'x86', 'x86_64', 'arm64-v8a', 'armeabi-v7a', 'armeabi'
universalApk false
}
}
}
3.System.loadLibrary("yousoname");
goodluck for you,it is ok with gradle 1.2.3
If your project exported from eclipse,add the codes below in gradle file:
android {
sourceSets{
main{
jniLibs.srcDir['libs']
}
}
}
2.If you create a project in Android studio:
create a folder named jniLibs in src/main/ ,and put your *.so files in the jniLibs folder.
And copy code as below in your gradle file :
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. 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.
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 ). In a nutshell, I recommend the following:
Don't upgrade your project to the latest gradle build
Use com.android.tools.build:gradle:1.5.0 in your Project root
Use com.android.application in your app project
Make sure gradle.properties has: android.useDeprecatedNdk=true (in case it's complaining)
Use the above approach to ensure that your hours and hours of effort creating Android.mk files won't be tossed away. 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.
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. This NDK feature has been "coming soon" for almost 3+ years.