How to use the Renderscript Support Library with Gradle - android

Is it possible to use the Support Renderscript Library with Gradle? If so, how do you include it in your project?

Using Android Studio:
Add the following values to build.gradle for android gradle plugin v0.14+
android {
...
defaultConfig {
...
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
}
...
}
For older versions of the android gradle plugin v0.13.3 and below
android {
...
defaultConfig {
...
renderscriptTargetApi 19
renderscriptSupportMode true
}
...
}
Once that is done, use android.support.v8.renderscript. anywhere in your app. The library jar and binaries are included automatically.

Gradle for Android has now Renderscript v8 support with only 2 lines in your build script. See answer by Austyn Mahoney. Keeping the original answer for historical purpose.
Old Answer:
Gradle supports native RS compilation, but not the RS support library. The reason is that the RS support library is hugely complicated compared to any other support library. The RS support library is actually a Java support library, a set of native libraries backing that Java lib, additional native libraries for every script you compile, and an alternate toolchain for generating both the standard LLVM bitcode and the native libraries for your scripts. Right now, only ADT and Ant support that; Gradle isn't there yet.
However, it's possible to use some parts of the RS support library from Gradle already. If you want to use the RS intrinsics, you can link the Java part of the support library (sdk/build-tools/android-4.3/lib/renderscript/renderscript-v8.jar) and the native components (sdk/build-tools/android-4.3/lib/renderscript/packaged/< arch >/*.so), and then you'll be set.
I know Gradle support for the support library is coming at some point in the not too distant future, but I don't have a firm ETA that I can share.

Following Tim's hint, I was able to get v8 support working with Gradle, here is my project layout:
I created libs folder, and copied files Tim mentioned under the SDK folder. And here is my build.gradle changes:
dependencies {
compile files('libs/renderscript-v8.jar')
}
android {
tasks.withType(com.android.build.gradle.tasks.PackageApplication) {
pkgTask -> pkgTask.jniFolders = new HashSet<File>();
pkgTask.jniFolders.add(new File(projectDir, 'libs'));
}
}
After that, I can import android.support.v8.renderscript.* and use the intrinsics.

I know this has been already answered, but I thought I'd share my experience with Android-Studio and Renderscript support with Build-tools 21.1.0.
This is what I found in build-system changelog lines 26-32:
Renamed a few properties to make things more consistent.
BuildType.runProguard -> minifyEnabled
BuildType.zipAlign -> zipAlignEnabled
BuildType.jniDebugBuild -> jniDebuggable
BuildType.renderscriptDebug -> renderscriptDebuggable
ProductFlavor.renderscriptSupportMode -> renderscriptSupportModeEnabled
ProductFlavor.renderscriptNdkMode -> renderscriptNdkModeEnabled
So you see, they have changed the properties name.
I just updated build.gradle to use:
renderscriptSupportModeEnabled true
Now the libraries are added to the project and you don't need to manually add them to your lib folder.

There is experimental support in the Gradle Android plugin at the time of this writing. See this test project for more info.

If anyone is interested in how to package this as a distributable binary .jar (e.g. for deploying to a maven repo) you can use this file structure for your .jar.
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>android</groupId>
<artifactId>renderscript</artifactId>
<version>19.0.3</version>
<description>Artifactory auto generated POM</description>
</project>
For build.gradle, add: compile 'android:renderscript:19.0.3' to your dependencies clojure.
PS: The renderscript library won't run on armv6 (armeabi), so make sure that Build.CPU_ABI is either armeabi-v7a, mips or x86.

Related

Releasing Android Library without NDK dependency

I am building a .aar Library that is partially written in C++ and uses OpenCV.
When i am assembling the Library i get a .aar with everything included and i can import it into a different project. When building the project i get the error, that i still need the correct ndk in the project which imports the .aar. This is not good if i want to give the library to others.
Shouldn't the JNI part of the library already be compiled so i don't need the NDK if i already have the .aar?
How can i remove the dependency from the .aar?
Edit:
The Error is No version of NDK matched the requested version 20.0.5594570. Versions available locally: 17.3.6528147, 21.0.6113669
I include the .aar by putting it in the libs/ folder in the module and adding '*.aar' to the build.gradle fileTree implementation.
The reason for it was the automatic stripping of the native part of my library.
Explaination here: https://stackoverflow.com/a/62320616/4284799
Solution 1: Change gradle version in the projects build.gradle
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
}
Solution 2: install a ndk and set it in the local.properties
ndk.dir=/path/to/android-sdk/ndk-bundle

Android experimental gradle plugin & Android Studio 3

I have an Android project and we have been using the experimental Gradle Plugin for some time. with Android Studio 3 being announced and the move to Gradle 4, I have a couple of questions
In just looking no one has added a new experimental gradle release in a couple of months, and the last version 11 alpha is 3 months ago. Is this still being maintained?
Is there a better way to do complicated NDK builds then the experimental Gradle plugin? I did a little research and it looks like there is a way to have a cMake txt file and call that as they did with this Samba client
https://github.com/google/samba-documents-provider/tree/master/app
When I say complicated NDK build, I have a number of C++ libraries I'm pulling together. I have a bunch of custom c++ code, I have a couple of 3rd party libraries that have their own code as well as shared libraries. And I have a number of jni interface files to manage it all.
I shortened this example, but I have 12 so files.
model {
// this repositories section defines our list of external shared libraries
// included here are all nuance libs and python 3.5
repositories {
libs(PrebuiltLibraries) {
lib1 {
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("src/main/jniLibs/${targetPlatform.getName()}/lib1.so")
}
}
lib2{
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("src/main/jniLibs/${targetPlatform.getName()}/lib2.so")
}
}
}
}
I then have the following for an NDK section
// defines the NDK build
ndk {
moduleName "myApp"
toolchain = "clang"
// We set the platform for the NDK. with the a certain device we were getting missing libraries without it
// https://github.com/android-ndk/ndk/issues/126
platformVersion="23"
// If switching to GNU, here are the values to replace with
stl "gnustl_shared"
CFlags.addAll(["-DNDEBUG"])
cppFlags.addAll(["-fexceptions", "-std=gnu++11"])
// when adding system library dependencies, they are added here
ldLibs.addAll(["log","atomic"])
// C include directories
CFlags.addAll(["-I${file("src/main/jni/lib1/inc")}".toString(),
"-I${file("src/main/jni/lib2")}".toString()
])
// C++ include directories
cppFlags.addAll(["-I${file("src/main/jni/lib1/inc")}".toString(),
"-I${file("src/main/jni/lib1")}".toString(),
"-I${file("src/main/jni/lib2")}".toString(),
"-I${file("src/main/jni/lib2/os")}".toString(),
"-I${file("src/main/jni")}".toString()
])
}
`
Then also in the gradle I list all my jni sources
// this section is to list the NDK static/shared library dependencies
// these dependencies are defined in detail above in the repositories section
sources {
main {
jni {
dependencies {
library "lib1"
library "lib2"
library "lib3"
library "lib4"
library "lib5"
library "lib6"
library "lib7"
library "lib8"
library "lib9"
library "lib10"
library "lib11"
library "lib12"
}
}
}
}
So to answer my own questions above.
It's been announced that the experimental gradle plugin will no longer be supported after 0.11.0. So no it's no longer maintained.
My project was converted over to use CMake. With the latest gradle 4.1 and converting everything to CMake and the CMakeLists.txt type of build we were able to get the project to build without the experimental version of gradle.

How to include a .so library and .c files in Android Studio 1.5

How can I add a .so library in Android Studio and make calls to it through a .c file with native code?
I have googled for a week and I've tried every posible solution I've found but nothing.
The sites are this, this, this, this, and more...
I arrived to make calls to a native .c file but I cannot include the .so library because Android studio cannot find it.
I don't want to use the new experimental gradle yet.
The environment configuration is the next one:
Android Studio 1.5
Gradle 2.8
Android plugin version 1.3.0
JDK 1.8.0
This is part of my code and gradle configuration:
GRADLE FILE
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
....
ndk {
moduleName "ffmpegkit"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
PROJECT STRUCTURE
INCLUDE STATEMENTS IN .C FILE
As you can see, "libavcodec.so" is not found but the project structure is the correct according to some solutions I've found.
Does anybody know how can I solve this problem and use these .so libraries with .c files?
Thank you very much!
I assume your .c file is somewhere under ffmpegkit directory in your project. You copied the ffmpeg binaries to your project's jniLibs, too. So far so good.
You need to provide the path to ffmpeg include files so that your .c files could compile. You also must list the libraries that the linker needs to find the external references of libffmpegkit.so that you are building:
defaultConfig {
....
ndk {
moduleName "ffmpegkit"
abiFilter "armeabi"
cFlags "-I/qqq/ffmpeg"
ldLibs "-llog -L src/main/libs", "avformat", "avcodec", "avutil"
}
}
Make sure that the ffmpeg libraries are compiled with a compatible Android toolchain! Note that the order in which ffmpeg libraries are listed is important. Like, libavformat depends on libavcodec, therefore it should go before.

Enabling of renderscript makes app to ignore jniLibs

I want to use some jni libraries. So I put binaries like this:
project
-app
--jnilibs
---armeabi
----libqwerty.so
and in my build.gradle (app module):
sourceSets.main {
jniLibs.srcDirs = ['jniLibs']
}
it works as expected, however when I add renderscript to my project:
renderscriptTargetApi 22
renderscriptSupportModeEnabled true
application doesn't see my jniLibs directory anymore. And the content of getApplicationInfo().nativeLibraryDir is: [libRSSupport.so, librsjni.so]
UPDATE: ok, I was able to resolve this issue with just renaming directory armeabi to armeabi-v7a. However what if I want to support some other cpu-architectures?
See the answer by a Google developer: renderscript libraries are not supported for Arm v6 and they have no plans to port them back. As for x86, MIPS, and 64-bit versions, Gradle will automagically add appropriate RS binaries to your APK.

Android studio, gradle and NDK

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.

Categories

Resources