I am attempting to add a native library to my existing application. My goal is to have the C++ library compile in it's own module in Android Studio using the plugin without manual steps (if possible). I have tried a multitude of suggestions and gotten hints that there is an issue with the build system for copying libraries between modules into the build. I have not been able to solve the problem.
Here are the relevant parts (and some) of my setup:
Android Studio:
Gradle Version: 2.10
Project File Structure:
myproject
+libmodule
| +src/main
| | +java
| | | `-MyWrapper.java
| | `jni
| | `-MyJNI.cpp
| `-build.gradle
+appmodule
| +src/main
| | `java
| | `-MyClass.java
| `-build.gradle
+gradle/wrapper
| `-gradle-wrapper.properties
+-build.gradle
`-settings.gradle
myproject/settings.gradle:
include ':appmodule', ':libmodule'
myproject/build.gradle:
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.6.0-alpha9'
}
}
allprojects {
repositories {
mavenCentral()
}
}
gradle-wrapper.properties:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
myproject/libmodule/build.gradle:
apply plugin: 'com.android.model.library'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = 23
}
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file("proguard-rules.txt"))
proguardFiles.add(file("proguard-android.txt"))
}
}
android.ndk {
moduleName = "MyLibrary"
stl = "gnustl_shared"
cppFlags.add("-nostdinc++")
cppFlags.add("-I\$(NDK)/sources/cxx-stl/stlport/stlport")
cppFlags.add("-fexceptions")
cppFlags.add("-frtti")
cppFlags.add("-fpermissive")
ldFlags.add("-nodefaultlibs")
ldFlags.add("-Lsrc/main/jniLibs/armeabi-v7a")
ldLibs.add("c")
ldLibs.add("m")
ldLibs.add("dl")
ldLibs.add("log")
ldLibs.add("gcc")
}
android.productFlavors {
create("arm") {
ndk.abiFilters.add("armeabi")
}
create("arm7") {
ndk.abiFilters.add("armeabi-v7a")
}
create("arm8") {
ndk.abiFilters.add("arm64-v8a")
}
create("x86") {
ndk.abiFilters.add("x86")
}
create("x86-64") {
ndk.abiFilters.add("x86_64")
}
create("mips") {
ndk.abiFilters.add("mips")
}
create("mips-64") {
ndk.abiFilters.add("mips64")
}
create("all")
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.1.1'
}
myproject/appmodule/build.gradle:
apply plugin: 'com.android.model.application'
buildscript {
repositories {
mavenCentral()
}
dependencies {
}
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile project(':libmodule')
// Support Libraries
// Maven Provided Libraries
compile fileTree(dir: 'libs', include: ['*.jar'])
}
model {
android {
compileSdkVersion = 23
buildToolsVersion = '23.0.2'
defaultConfig.with {
applicationId = "com.me.myandroidapp"
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = 23
}
}
android.dexOptions {
jumboMode = true
}
android.packagingOptions {
//Some specific removals for an included lib from maven
}
android.lintOptions {
checkReleaseBuilds = false
abortOnError = false
}
android.buildTypes {
debug {
debuggable = true
minifyEnabled = false
buildConfigFields.with {
create() {
type = "boolean"
name = "SCREENSHOTS"
value = "true"
}
}
buildConfigFields.with {
create() {
type = "boolean"
name = "DEBUGGABLE"
value = "true"
}
}
proguardFiles.add(file("proguard-rules.txt"))
proguardFiles.add(file("proguard-android.txt"))
}
release {
debuggable = false
minifyEnabled = true
buildConfigFields.with {
create() {
type = "boolean"
name = "SCREENSHOTS"
value = "false"
}
}
buildConfigFields.with {
create() {
type = "boolean"
name = "DEBUGGABLE"
value = "false"
}
}
proguardFiles.add(file("proguard-rules.txt"))
proguardFiles.add(file("proguard-android.txt"))
}
}
android.productFlavors {
create("prod") {
applicationId = "com.me.myandroidapp"
}
create("dev") {
applicationId = "com.me.myandroidapp"
}
create("beta") {
applicationId = "com.me.myandroidapp"
}
create("staging") {
applicationId = "com.me.myandroidapp"
}
}
}
if (project.hasProperty("MyProject.properties") && new File(project.property("MyProject.properties")).exists()) {
// Get properties in the property file
Properties props = new Properties()
props.load(new FileInputStream(file(project.property("MyProject.properties"))))
model {
android {
signingConfigs {
//several configs here
}
}
android.buildTypes {
release {
signingConfig = signingConfigs.release
}
}
}
}
MyWrapper.java:
package com.me.androidwrapper;
public class MyWrapper {
private native String doItNatively(String stringinput);
public String doIt(String stringinput) {
return doItNatively(stringinput);
}
static {
System.loadLibrary("MyLibrary");
}
}
myjni.cpp:
extern "C" {
JNIEXPORT jstring JNICALL
Java_com_me_androidwrapper_MyWrapper_doItNatively(JNIEnv *env, jobject instance, jstring stringinput_) {
// C++ happens here
}
}
MyClass.java:
// Weird behavior for IDE adding dependency module happens here:
import com.me.androidwrapper.MyWrapper;
public class MyClass {
public String makeItHappen(String inputstring) {
MyWrapper mywrapper = new myWrapper();
return mywrapper.doIt(inputstring);
}
}
There are no android.mk files in the JNI.
From a cleaned project gradle executes successfully. When I run Make Module on appmodule I get the error:
Error:(5, 37) error: package com.me.androidwrapper does not exist
...and the import statement from MyClass.java is highlighted.
As noted above in the code for MyClass.java, Android Studio offers a quick fix for including a dependency for Module "libmodule" and if I select it the IDE drops the errors. The IDE then resolves the project links correctly if I command-click through the package, class or methods.
I have followed a number of solutions on StackOverflow and in groups for the plugin. There is mention of the new experimental plug-in and build system not copying native libraries between modules in several of them and I have tried methods that set up a aar/jar module as an intermediary. I have also tried methods for manually copying the aar file into the module lib and referencing it as a file or as an aar. Most of these methods have not worked, the best result I have had is to have a successful build, but the application crashes not finding libMyLibrary.so
I have successfully tested the project by including the JNI directly into the appmodule Module using gradle 2.8 with android experimental plugin 0.4.0. This is not a very good solution as the module is complex and the C++ code is maintained separately. The 0.4.0 plugin fails as a multi-module, the library's .so does not package.
There are gaps in my knowledge of the new experimental plugin and I know it has bugs, it is incomplete and some features are still in discussion. Any assistance in tracking down my mistake, or providing a comprehensive work around to the plugin's lack of features would be greatly appreciated.
If you want to add some native libraries to your existing application in Android studio, you can do it in three standard ways. Please read this link https://stackoverflow.com/a/35369267/5475941. In this post I explained how to import your JAR files in Android studio and I explained all possible ways step by step with screenshots. I hope it helps.
Related
I have 4 gradle build files: when I build in android studio I am constantly having the error:
No signature of method:
org.gradle.model.ModelMap.getDefaultProguardFile() is applicable for
argument types: (java.lang.String) values: [proguard-android.txt]
file 1
// 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.9.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
file 2
apply plugin: 'com.android.model.native'
model {
android {
compileSdkVersion = 25
buildToolsVersion = '25.0.0'
defaultConfig {
minSdkVersion.apiLevel = 17
targetSdkVersion.apiLevel = 25
versionCode = 1
versionName = '1.0'
}
ndk {
moduleName = 'fpextractor'
platformVersion = 17
toolchain = "clang"
stl = 'gnustl_static' //std::mutex not in gnustl_static
cppFlags.add('-std=c++11')
abiFilters.addAll(['armeabi', 'armeabi-v7a', 'x86'])
//abiFilters.addAll(['armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64']) //this is default
//abiFilters.addAll(['armeabi'])
ldLibs.addAll(['android', 'log', 'atomic', 'z'])
}
}
}
// This is just copy out the header file and built lib into distribution
// directory for clint application to use; it is a small overhead of this sample:
// both lib and app are put inside one project space [save maintenance time]
task(distributeLib, type : Copy) {
// trigger build library
dependsOn assemble
into '../distribution/fpextractor/'
from('src/main/jni/fp_extractor.h') {
into 'include/'
}
from('build/outputs/native/release/lib') {
into 'lib/'
}
}
file 3
apply plugin: 'com.android.model.native'
model {
android {
compileSdkVersion = 25
buildToolsVersion = '25.0.0'
defaultConfig {
minSdkVersion.apiLevel = 17
targetSdkVersion.apiLevel = 25
versionCode = 1
versionName = '1.0'
}
ndk {
moduleName = 'nativeaudio'
platformVersion = 17
toolchain = "clang"
stl = 'gnustl_static' //std::mutex not in gnustl_static
cppFlags.add('-std=c++11')
abiFilters.addAll(['armeabi', 'armeabi-v7a', 'x86'])
//abiFilters.addAll(['armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64']) //this is default
//abiFilters.addAll(['armeabi-v7a'])
ldLibs.addAll(['android', 'log', 'OpenSLES', 'atomic'])
}
}
}
// This is just copy out the header file and built lib into distribution
// directory for clint application to use; it is a small overhead of this sample:
// both lib and app are put inside one project space [save maintenance time]
task(distributeLib, type : Copy) {
// trigger build library
dependsOn assemble
into '../distribution/nativeaudio/'
from('src/main/jni/buf_manager.h') {
into 'include/'
}
from('src/main/jni/android_debug.h') {
into 'include/'
}
from('src/main/jni/debug_utils.h') {
into 'include/'
}
from('src/main/jni/audio_common.h') {
into 'include/'
}
from('src/main/jni/audio_recorder.h') {
into 'include/'
}
from('build/outputs/native/release/lib') {
into 'lib/'
}
}
file 4
apply plugin: 'com.android.model.application'
// Root of 3rd party lib(s): location could be anywhere on the host system
def lib_distribution_root = '../distribution'
model {
repositories {
libs(PrebuiltLibraries) {
// Configure one pre-built lib: shared
nativeaudio {
// Inform Android Studio where header file dir for this lib
headers.srcDir "${lib_distribution_root}/nativeaudio/include"
// Inform Android Studio where lib is -- each ABI should have a lib file
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("${lib_distribution_root}/nativeaudio/lib/${targetPlatform.getName()}/libnativeaudio.so")
}
}
fpextractor {
// Inform Android Studio where header file dir for this lib
headers.srcDir "${lib_distribution_root}/fpextractor/include"
// Inform Android Studio where lib is -- each ABI should have a lib file
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("${lib_distribution_root}/fpextractor/lib/${targetPlatform.getName()}/libfpextractor.so")
}
}
// Configure another pre-built lib: shared;[change to static after Studio supports]
// static lib generation. USING static lib is supported NOW, for that case,
// simple change:
// SharedLibaryBinary --> StaticLibraryBinary
// sharedLibraryFile --> staticLibraryFile
// *.so --> *.a
//gperf {
// headers.srcDir "${lib_distribution_root}/gperf/include"
// binaries.withType(SharedLibraryBinary) {
// sharedLibraryFile = file("${lib_distribution_root}/gperf/lib/${targetPlatform.getName()}/libgperf.so")
// }
//}
}
}
android {
compileSdkVersion = 25
buildToolsVersion = '25.0.0'
defaultConfig {
applicationId='com.gfk.mediawatchapp'
minSdkVersion.apiLevel = 17
targetSdkVersion.apiLevel = 25
versionCode = 22
versionName = '255.0.4'
// Enabling multidex support.
//multiDexEnabled true
}
ndk {
platformVersion = 17
moduleName = 'mwlib'
toolchain = "clang"
stl = 'gnustl_static'
cppFlags.add('-std=c++11')
ldLibs.addAll(['android', 'log', 'OpenSLES', 'atomic'])
//build a default combined apk including all ABIs.
//abiFilters.addAll(['armeabi-v7a'])
abiFilters.addAll(['armeabi', 'armeabi-v7a', 'x86']) //this is default
}
sources {
main {
jni {
dependencies {
library 'nativeaudio' linkage 'shared'
library 'fpextractor' linkage 'shared'
// if gperf were *.a, change shared --> static
//library 'gperf' linkage 'shared'
}
}
jniLibs {
// for shared lib, lib need to be pushed to the target too
// Once libs are copied into app/src/main/jniLibs directory,
// Android Studio will pack them into APK's lib/ directory
// Here we like to avoid another duplication by pointing
// to the files that containing our libs' distribution location
// so the same file is used by compiler at host, also packed
// into APk to be used at Target (phone/tablet)
source {
srcDir "${lib_distribution_root}/nativeaudio/lib"
srcDir "${lib_distribution_root}/fpextractor/lib"
//srcDir "${lib_distribution_root}/gperf/lib"
}
}
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles.add(file('proguard-android.txt'))
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
}
dependencies {
println rootProject.getName()
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:support-v4:25.3.1'
compile 'commons-net:commons-net:3.5'
//compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.android.support:cardview-v7:25.3.1'
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.google.android.gms:play-services-appindexing:9.8.0'
compile 'com.amazonaws:aws-android-sdk-core:2.4.2'
compile 'com.amazonaws:aws-android-sdk-s3:2.4.2'
compile 'com.amazonaws:aws-android-sdk-ddb:2.4.2'
compile 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.4.2'
}
// Unnecessary dependency management:
// Make sure the libs are available when begin compiling application project
// This could be ignored because in real scenario, the pre-built libs are
// already given to us before creating application.
tasks.whenTaskAdded { task ->
if (task.name.contains('compile')) {
task.dependsOn ':nativeaudio:distributeLib'
task.dependsOn ':fpextractor:distributeLib'
}
}
Please: Can anyone help me to understand why I have always the following error:
No signature of method:
org.gradle.model.ModelMap.getDefaultProguardFile() is applicable for
argument types: (java.lang.String) values: [proguard-android.txt]
Gradle experimental does not include getDefaultProguardFile() since it does not have any version of ProGuard config by default.
You can use move the lines from your proguard-android.txt to proguard-rules.pro and then change this line:
proguardFiles.add(file('proguard-android.txt'))
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
into this:
proguardFiles.add(file('proguard-rules.pro'))
For me adding a manifest with
jar {
manifest {
attributes 'Main-Class': com.package.to.main.Class
}
}
helped.
See here: Creating runnable JAR with Gradle
I have an Android NDK based project that uses the experimental gradle plugin. I am trying to add React Native and the React Native Navigation (RNN) module to the project
The example project that comes with RNN builds and runs as expected. However in order to make RNN compatible with my project I had to update its build.gradle file to work with the experimental gradle plugin: https://github.com/adamski/react-native-navigation/commit/0a848f574cedae83bf8961bd1fafe8a42e4257cc
I am hitting the following build error:
Error:(64, 1) error: package com.reactnativenavigation.activities does not exist
I have trawled SO and the web for a solution to this. I can see the project and navigate it in AS:
However on navigating to the main Activity java class, it shows red lines where it cannot find the dependency, even though it offers the option if importing the files to the main project(?).
My settings.gradle:
include ':app'
include ':react-native-navigation'
project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../../node_modules/react-native-navigation/android/app/')
The project build.gradle:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.7.0-rc1'
}
}
allprojects {
repositories {
jcenter()
maven { // All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../../node_modules/react-native/android" // node_modules is two levels up from the AndroidStudio project folder
}
}
}
The app's build.gradle:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "com.company.myapp"
minSdkVersion.apiLevel = 16
targetSdkVersion.apiLevel = 22
}
}
android.ndk {
moduleName = "juce_jni"
toolchain = "clang"
stl = "c++_static"
cppFlags.add("-fsigned-char")
cppFlags.add("-fexceptions")
cppFlags.add("-frtti")
cppFlags.add("-std=c++11")
cppFlags.add("-DJUCE_ENABLE_LIVE_CONSTANT_EDITOR=0")
cppFlags.add("-DJUCER_ANDROIDSTUDIO_4330F05B=1")
cppFlags.add("-DJUCE_APP_VERSION=0.4.0")
cppFlags.add("-DJUCE_APP_VERSION_HEX=0x400")
cppFlags.add("-I${project.rootDir}/../../Fonts".toString())
cppFlags.add("-I${project.rootDir}/../../Source".toString())
cppFlags.add("-I${project.rootDir}/../iOS".toString())
cppFlags.add("-I${project.rootDir}/../../../../juce_modules/adamski/PitchDetector/modules".toString())
cppFlags.add("-I${project.rootDir}/../../Source/LookAndFeel".toString())
cppFlags.add("-I${project.rootDir}/../../Source/Synth".toString())
cppFlags.add("-I${project.rootDir}/../../Source/UI".toString())
ldLibs.add("android")
ldLibs.add("EGL")
ldLibs.add("GLESv2")
ldLibs.add("log")
platformVersion = 15
}
android.sources {
main {
jni {
source {
exclude "**/JuceModules/"
}
}
}
}
android.buildTypes {
debug {
ndk.with {
debuggable = true
cppFlags.add("-g")
cppFlags.add("-DDEBUG=1")
cppFlags.add("-D_DEBUG=1")
cppFlags.add("-O0")
cppFlags.add("-I${project.rootDir}/../../JuceLibraryCode".toString())
cppFlags.add("-I${project.rootDir}/../../../../JUCE/modules".toString())
cppFlags.add("-I${project.rootDir}/../../../../juce_modules/adamski".toString())
cppFlags.add("-DJUCE_ANDROID=1")
cppFlags.add("-DJUCE_ANDROID_API_VERSION=21")
cppFlags.add("-DJUCE_ANDROID_ACTIVITY_CLASSNAME=com_company_myapp_MyApp")
cppFlags.add("-DJUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/company/myapp/MyApp\"")
cppFlags.add("-DJUCE_ENABLE_LIVE_CONSTANT_EDITOR=0")
}
}
release {
signingConfig = $("android.signingConfigs.releaseConfig")
ndk.with {
cppFlags.add("-DNDEBUG=1")
cppFlags.add("-O3")
cppFlags.add("-I${project.rootDir}/../../JuceLibraryCode".toString())
cppFlags.add("-I${project.rootDir}/../../../../JUCE/modules".toString())
cppFlags.add("-I${project.rootDir}/../../../../juce_modules/adamski".toString())
cppFlags.add("-DJUCE_ANDROID=1")
cppFlags.add("-DJUCE_ANDROID_API_VERSION=21")
cppFlags.add("-DJUCE_ANDROID_ACTIVITY_CLASSNAME=com_company_myapp_MyApp")
cppFlags.add("-DJUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/company/myapp/MyApp\"")
cppFlags.add("-DJUCE_ENABLE_LIVE_CONSTANT_EDITOR=0")
}
}
}
android.signingConfigs {
create("releaseConfig") {
storeFile = new File("/Users/adamelemental/.android/debug.keystore")
storePassword = "android"
keyAlias = "androiddebugkey"
keyPassword = "android"
storeType = "jks"
}
}
android.productFlavors {
create("armeabi") {
ndk.abiFilters.add("armeabi")
}
create("armeabi-v7a") {
ndk.abiFilters.add("armeabi-v7a")
}
create("x86") {
ndk.abiFilters.add("x86")
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:support-v4:+'
compile 'com.facebook.react:react-native:+'
// The following do not work with the experimental gradle plugin:
// debugCompile project(path: ':react-native-navigation', configuration: 'libraryDebug')
// releaseCompile project(path: ':react-native-navigation', configuration: 'libraryRelease')
compile project (':react-native-navigation')
}
Deleting the productFlavors part of RNN's build.gradle got past this issue.
I have added 2 .so prebuilt libraries to a new project in Android Studio which is using the experimental gradle plugin (com.android.tools.build:gradle-experimental:0.6.0-beta5).
My build.gradle file looks like this:
apply plugin: 'com.android.model.application'
model {
repositories {
prebuilt(PrebuiltLibraries) {
gstplayer {
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("libs/libgstplayer.so")
sharedLibraryFile = file("libs/libgstreamer_android.so")
}
}
}
}
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.myexample.gstreamertest2"
minSdkVersion.apiLevel 19
targetSdkVersion.apiLevel 23
versionCode 1
versionName "1.0"
buildConfigFields {
create() {
type "int"
name "VALUE"
value "1"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles.add(file('proguard-rules.pro'))
}
}
ndk {
moduleName "gstplayer"
}
productFlavors {
create("flavor1") {
applicationId "com.app"
}
}
// Configures source set directory.
sources {
main {
// jni {
// source {
// srcDirs = ['src/main/jni']
// }
// }
jniLibs {
dependencies {
library "gstplayer"
}
}
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
}
Gradle build is successful, but I can't find instructions anywhere on how to reference these libraries. I know that you can create public native String getInfoFromJni() in your Java file and reference native .c files in your jni folder, and I have been able to get this working, but I don't know how to do something similar with .so libraries.
How do I access the methods in the .so libraries from java?
You should create a wraper c lib:
1.- Change the name of the moduleName to avoid conflicts:
ndk {
moduleName "gstplayerwrapper"
}
2.- Load your wrapper lib in your activity
static{
System.loadLibrary("EcoLogSIL");
}
3.- Built your project
4.- Create a function which call the wrapper and press alt+intro
5.- You should have a new function inside gtsplayerwrapper.c and here you can call libgstplayer.so
JNIEXPORT void JNICALL
Java_your_activty_name_call_1wrapper(JNIEnv *env, jobject instance) {
// YOUR CODE HERE
}
Don't forget to import the library inside gtsplayerwrapper.c
EDIT add headers
repositories {
prebuilt(PrebuiltLibraries) {
gstplayer {
headers.srcDir "src/main/jni/include"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("libs/libgstplayer.so")
sharedLibraryFile = file("libs/libgstreamer_android.so")
}
}
}
}
Create this folder in your project and copy there .h files
I'm trying to use Experimental Gradle Plugin for my NDK projects, but it do not compile ndk. Everything looks fine - Android Studio understands my C code, can jump from Java to native and so on, but when i run "Build", step of compiling ndk is skipped - i see no tasks like "compileNdk".
When I list all available tasks by
gradlew tasks
there is no taks like "compileNdk" also. "Libs" folder are empty too, so when I try to call native method, app crash with "UnsatisfiedLinkError".
So what am i missing? How to tell gradle to compile NDK?
My config is:
root build.gradle:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.3.0-alpha5'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
module build.gradle:
apply plugin: 'com.android.model.application'
model
{
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.1"
defaultConfig.with {
applicationId = "com.kaspersky.experimentalcpp"
minSdkVersion.apiLevel = 14
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
}
android.buildTypes {
debug {
ndk.with {
debuggable = true
}
}
release {
minifyEnabled = false
proguardFiles += file('proguard-rules.pro')
}
}
android.sources {
main {
jni {
source {
srcDirs 'src/main/jni'
}
}
}
}
android.ndk {
moduleName = "test_experimental"
stl = "stlport_static"
cppFlags += "-Isrc/main/jni".toString()
ldLibs += ["log"]
ldLibs += ["android"]
}
android.productFlavors {
create("arm") {
ndk.abiFilters += "armeabi"
}
create("arm7") {
ndk.abiFilters += "armeabi-v7a"
}
create("fat")
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.0'
}
I'm using Android Studio 1.4.1 on Windows 7. ndk.dir points to "ndk-bundle" folder which was downloaded by AS.
Any help appreciated!
So after some research I figured out that my libs actually compiles, they just puts not in the "libs" folder, but in "build/intermediates/binaries/...". I dump result .so and figured that my JNI methods was not in there. The reason was that my JNI methods was declared in .h file. After renaming .h to .cpp all works fine (except debugging). Maybe it will help somebody else!
Recently i decided to take the new NDK plugin in Android Studio for a ride
The changes needed are explained here
My build.gradle was ported successfully. Today i decided that i need a copy task in order to copy files into my 'asset' folder.
Searching online says that i must use a 'preBuild.dependsOn taskName' line, which i am sure works Ok for normal Gradle, but fails in the new experimental one (With the introduction of the 'model' behaviour)
Now my build.gradle fails.
Error:(25, 0) Could not find property 'preBuild' on root project 'Android'.
I am sure that the task is defined correctly, since the error comes from the preBuild... line
Here is my build.gradle:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.2.0'
}
}
allprojects {
repositories {
jcenter()
}
}
apply plugin: 'com.android.model.application'
task copyWebViewAssets(type: Copy){
from '../Common/WebView'
into 'src/main/assets'
include('**/*')
}
preBuild.dependsOn copyWebViewAssets
model {
compileOptions.with {
sourceCompatibility=JavaVersion.VERSION_1_7
targetCompatibility=JavaVersion.VERSION_1_7
}
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.1"
defaultConfig.with {
applicationId = "com.company.product"
minSdkVersion.apiLevel = 9
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
}
android.ndk {
moduleName = "native"
}
android.buildTypes {
release {
minifyEnabled = false
}
debug {
ndk.with {
debuggable = true
}
}
}
android.productFlavors {
// To include all cpu architectures, leaves abiFilters empty
create("all")
}
}
dependencies {
compile 'com.android.support:appcompat-v7:23.0.1'
}
I would like to address again that this is related to the new experimental Gradle for NDK. I am currently on Android Studio 1.4, using Gradle 2.5.
Thank you for your support
Use compileTask instead of prebuild
it works for me.
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn(changeNamespace)
}