I was able to successfully run my project in Eclipse. But when i am trying to upgrade my project to Android studio it stopped working for me. I have tried every thing but it is not working. Below is my build.gradle file code.
apply plugin: 'android'
buildscript {
repositories {
mavenCentral()
}
// Switch the Android Gradle plugin version requirement depending on the
// installed version of Gradle. This dependency is documented at
// http://tools.android.com/tech-docs/new-build-system/version-compatibility
// and https://issues.apache.org/jira/browse/CB-8143
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
}
}
// Allow plugins to declare Maven dependencies via build-extras.gradle.
repositories {
mavenCentral()
}
task wrapper(type: Wrapper) {
gradleVersion = '2.2.1'
}
// Configuration properties. Set these via environment variables, build-extras.gradle, or gradle.properties.
// Refer to: http://www.gradle.org/docs/current/userguide/tutorial_this_and_that.html
ext {
apply from: 'CordovaLib/cordova.gradle'
// The value for android.compileSdkVersion.
if (!project.hasProperty('cdvCompileSdkVersion')) {
cdvCompileSdkVersion = privateHelpers.getProjectTarget()
}
// The value for android.buildToolsVersion.
if (!project.hasProperty('cdvBuildToolsVersion')) {
cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
}
// Sets the versionCode to the given value.
if (!project.hasProperty('cdvVersionCode')) {
cdvVersionCode = null
}
// Sets the minSdkVersion to the given value.
if (!project.hasProperty('cdvMinSdkVersion')) {
cdvMinSdkVersion = null
}
// Whether to build architecture-specific APKs.
if (!project.hasProperty('cdvBuildMultipleApks')) {
cdvBuildMultipleApks = false
}
// .properties files to use for release signing.
if (!project.hasProperty('cdvReleaseSigningPropertiesFile')) {
cdvReleaseSigningPropertiesFile = null
}
// .properties files to use for debug signing.
if (!project.hasProperty('cdvDebugSigningPropertiesFile')) {
cdvDebugSigningPropertiesFile = null
}
// Set by build.js script.
if (!project.hasProperty('cdvBuildArch')) {
cdvBuildArch = null
}
}
def hasBuildExtras = file('build-extras.gradle').exists()
if (hasBuildExtras) {
apply from: 'build-extras.gradle'
}
def computeBuildTargetName(debugBuild) {
def ret = 'assemble'
if (cdvBuildMultipleApks && cdvBuildArch) {
def arch = cdvBuildArch == 'arm' ? 'armv7' : cdvBuildArch
ret += '' + arch.toUpperCase().charAt(0) + arch.substring(1);
}
return ret + (debugBuild ? 'Debug' : 'Release')
}
// Make cdvBuild a task that depends on the debug/arch-sepecific task.
task cdvBuildDebug
cdvBuildDebug.dependsOn {
return computeBuildTargetName(true)
}
task cdvBuildRelease
cdvBuildRelease.dependsOn {
return computeBuildTargetName(false)
}
task cdvPrintProps << {
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
println('cdvVersionCode=' + cdvVersionCode)
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
println('cdvBuildArch=' + cdvBuildArch)
println('computedVersionCode=' + android.defaultConfig.versionCode)
if (android.productFlavors.has('armv7')) {
println('computedArmv7VersionCode=' + android.productFlavors.armv7.versionCode)
}
if (android.productFlavors.has('x86')) {
println('computedx86VersionCode=' + android.productFlavors.x86.versionCode)
}
}
// PLUGIN GRADLE EXTENSIONS START
// PLUGIN GRADLE EXTENSIONS END
android {
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
def versionCodeOverride = cdvVersionCode ? Integer.parseInt(cdvVersionCode) : null
def minSdkVersionOverride = cdvMinSdkVersion ? Integer.parseInt(cdvMinSdkVersion) : null
defaultConfig {
versionCode versionCodeOverride ?: Integer.parseInt("" + privateHelpers.extractIntFromManifest("versionCode") + "0")
if (minSdkVersionOverride != null) {
minSdkVersion minSdkVersionOverride
}
}
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
if (Boolean.valueOf(cdvBuildMultipleApks)) {
productFlavors {
armv7 {
versionCode versionCodeOverride ?: defaultConfig.versionCode + 2
ndk {
abiFilters "armeabi-v7a", ""
}
}
x86 {
versionCode versionCodeOverride ?: defaultConfig.versionCode + 4
ndk {
abiFilters "x86", ""
}
}
all {
ndk {
abiFilters "all", ""
}
}
}
} else if (!versionCodeOverride) {
def minSdkVersion = minSdkVersionOverride ?: privateHelpers.extractIntFromManifest("minSdkVersion")
// Vary versionCode by the two most common API levels:
// 14 is ICS, which is the lowest API level for many apps.
// 20 is Lollipop, which is the lowest API level for the updatable system webview.
if (minSdkVersion >= 20) {
defaultConfig.versionCode += 9
} else if (minSdkVersion >= 14) {
defaultConfig.versionCode += 8
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6
targetCompatibility JavaVersion.VERSION_1_6
}
if (cdvReleaseSigningPropertiesFile) {
signingConfigs {
release {
// These must be set or Gradle will complain (even if they are overridden).
keyAlias = ""
keyPassword = "__unset" // And these must be set to non-empty in order to have the signing step added to the task graph.
storeFile = null
storePassword = "__unset"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
addSigningProps(cdvReleaseSigningPropertiesFile, signingConfigs.release)
}
if (cdvDebugSigningPropertiesFile) {
addSigningProps(cdvDebugSigningPropertiesFile, signingConfigs.debug)
}
}
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
// SUB-PROJECT DEPENDENCIES START
// SUB-PROJECT DEPENDENCIES END
}
def promptForReleaseKeyPassword() {
if (!cdvReleaseSigningPropertiesFile) {
return;
}
if ('__unset'.equals(android.signingConfigs.release.storePassword)) {
android.signingConfigs.release.storePassword = privateHelpers.promptForPassword('Enter key store password: ')
}
if ('__unset'.equals(android.signingConfigs.release.keyPassword)) {
android.signingConfigs.release.keyPassword = privateHelpers.promptForPassword('Enter key password: ');
}
}
gradle.taskGraph.whenReady { taskGraph ->
taskGraph.getAllTasks().each() { task ->
if (task.name == 'validateReleaseSigning') {
promptForReleaseKeyPassword()
}
}
}
def addSigningProps(propsFilePath, signingConfig) {
def propsFile = file(propsFilePath)
def props = new Properties()
propsFile.withReader { reader ->
props.load(reader)
}
def storeFile = new File(privateHelpers.ensureValueExists(propsFilePath, props, 'storeFile'))
if (!storeFile.isAbsolute()) {
storeFile = RelativePath.parse(true, storeFile.toString()).getFile(propsFile.getParentFile())
}
if (!storeFile.exists()) {
throw new FileNotFoundException('Keystore file does not exist: ' + storeFile.getAbsolutePath())
}
signingConfig.keyAlias = privateHelpers.ensureValueExists(propsFilePath, props, 'keyAlias')
signingConfig.keyPassword = props.get('keyPassword', signingConfig.keyPassword)
signingConfig.storeFile = storeFile
signingConfig.storePassword = props.get('storePassword', signingConfig.storePassword)
def storeType = props.get('storeType')
if (!storeType) {
def filename = storeFile.getName().toLowerCase();
if (filename.endsWith('.p12') || filename.endsWith('.pfx')) {
storeType = 'pkcs12'
}
}
if (storeType) {
signingConfig.storeType = storeType
}
}
// This can be defined within build-extras.gradle as:
// ext.postBuildExtras = { ... code here ... }
if (hasProperty('postBuildExtras')) {
postBuildExtras()
}
Once i run the code and try to open my application custom keyboard get following exception.
E/BinaryDictionary: Could not load native library jni_latinime
12-06 15:22:01.269 8412-8412/com.KGP.inputmethod.latin E/art: No implementation found for int com.android.inputmethod.latin.BinaryDictionary.openNative(java.nio.ByteBuffer, int, int) (tried Java_com_android_inputmethod_latin_BinaryDictionary_openNative and Java_com_android_inputmethod_latin_BinaryDictionary_openNative__Ljava_nio_ByteBuffer_2II)
12-06 15:22:01.270 8412-8412/com.KGP.inputmethod.latin D/AndroidRuntime: Shutting down VM
12-06 15:22:01.271 8412-8412/com.KGP.inputmethod.latin E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.KGP.inputmethod.latin, PID: 8412
java.lang.UnsatisfiedLinkError: No implementation found for int com.android.inputmethod.latin.BinaryDictionary.openNative(java.nio.ByteBuffer, int, int) (tried Java_com_android_inputmethod_latin_BinaryDictionary_openNative and Java_com_android_inputmethod_latin_BinaryDictionary_openNative__Ljava_nio_ByteBuffer_2II)
at com.android.inputmethod.latin.BinaryDictionary.openNative(Native Method)
at com.android.inputmethod.latin.BinaryDictionary.loadDictionary(BinaryDictionary.java:151)
at com.android.inputmethod.latin.BinaryDictionary.<init>(BinaryDictionary.java:82)
at com.android.inputmethod.latin.Suggest.<init>(Suggest.java:114)
at com.android.inputmethod.latin.LatinIME.initSuggest(LatinIME.java:494)
at com.android.inputmethod.latin.LatinIME.onCreate(LatinIME.java:399)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2945)
at android.app.ActivityThread.access$1900(ActivityThread.java:159)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1467)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:152)
at android.app.ActivityThread.main(ActivityThread.java:5507)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Below is my project folder structure :-
My Class code where i am uploading lib :-
static {
try {
System.loadLibrary("jni_latinime_moo");
} catch (UnsatisfiedLinkError ule) {
Log.e("BinaryDictionary",
"Could not load native library jni_latinime");
}
}
I am not sure what i am doing wrong here. I am very thankful who ever can help me out.
I have resolved my issue using this link :-
stackoverflow.com/questions/21096819/jni-and-gradle-in-android-studio
Related
I get this error when I add this to Android Studio
"Error:Plugin with id 'kotlin-android' not found.".
I am trying to install opencv on my android, but it will not work.
I made a new project in my Android that is empty but works
My build gradle
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
def openCVersionName = "4.5.4"
def openCVersionCode = ((4 * 100 + 5) * 100 + 4) * 10 + 0
println "OpenCV: " +openCVersionName + " " + project.buildscript.sourceFile
android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 21
targetSdkVersion 26
versionCode openCVersionCode
versionName openCVersionName
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared"
targets "opencv_jni_shared"
}
}
}
buildTypes {
debug {
packagingOptions {
doNotStrip '**/*.so' // controlled by OpenCV CMake scripts
}
}
release {
packagingOptions {
doNotStrip '**/*.so' // controlled by OpenCV CMake scripts
}
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['native/libs']
java.srcDirs = ['java/src']
aidl.srcDirs = ['java/src']
res.srcDirs = ['java/res']
manifest.srcFile 'java/AndroidManifest.xml'
}
}
externalNativeBuild {
cmake {
path (project.projectDir.toString() + '/libcxx_helper/CMakeLists.txt')
}
}
}
dependencies {
}
I ran into the same error with Android Studio 2020.3.1 and fixed the error by adding this on top of the skd's build gradle (above 'apply plugin...'):
buildscript {
ext {
kotlinVersion = "1.4.0"
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
repositories {
mavenCentral()
}
}
I have a strange issue.
I have this kotlin piece of code that sorts a dictionary, inside my multidix mixed java-kotlin application. (code below)
when running the app on development phone (SAMSUNG s9) everything runs ok.
When deployed the app to Fabric's "beta", a big portion (50%) of the users are having crashes of type NoClassDefFoundError.
The affected phones include xioami's MI 5s and Red-mi phones and multiple types of onePlus phones
I tried to look at the output apk (via build -> Analyze APK) and made sure the class is, indeed, there. As you can see from - that the class is actually on the main "classes.dex" file.
Any help will be much appreciated!
log file:
... (custom logging from the app on initiation level)
09-09 13:04:31.667 17365-17365/com.example.orcam.basic_recognition_app
I/art: Rejecting re-init on previously-failed class java.lang.Class<com.example.orcam.logic_myme.ComputedData.ComputedPersonData$calculateMeetingsForPerson$2>
... (custom logging from the app on normal run level)
09-09 13:04:31.762 17365-17365/com.example.orcam.basic_recognition_app
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.orcam.basic_recognition_app, PID: 17365
java.lang.NoClassDefFoundError: com.example.orcam.logic_myme.ComputedData.ComputedPersonData$calculateMeetingsForPerson$2
at com.example.orcam.logic_myme.ComputedData.ComputedPersonData.calculateMeetingsForPerson(ComputedPersonData.kt:45)
at com.example.orcam.logic_myme.ComputedData.ComputedData.calculate(ComputedData.kt:7)
at com.example.orcam.logic_myme.db.DBManager$init$2.onDbInitAndReady(DBManager.kt:79)
at com.example.lib_sync.sync.SyncManager2.(SyncManager2.java:63)
at com.example.orcam.logic_myme.db.DBManager.init(DBManager.kt:76)
at com.example.orcam.basic_recognition_app.LogicManager.init(LogicManager.java:58)
at com.example.orcam.basic_recognition_app.MyMeApplication.initManagers(MyMeApplication.kt:31)
at com.example.orcam.basic_recognition_app.MyMeApplication.onCreate(MyMeApplication.kt:13)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1014)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4782)
at android.app.ActivityThread.access$1700(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1445)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:5544)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629) 09-09
13:04:31.763 17365-17365/com.example.orcam.basic_recognition_app
E/MQSEventManagerDelegate: failed to get MQSService.
build.gradle file:
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
google()
}
dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
repositories {
maven { url 'https://maven.fabric.io/public' }
google()
}
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
defaultConfig {
applicationId "com.example.orcam.basic_recognition_app"
minSdkVersion 21
targetSdkVersion 27
versionCode 29
versionName "5.0.9"
}
buildTypes {
debug {
applicationIdSuffix ".debug"
}
beta {
initWith debug
applicationIdSuffix ""
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
pickFirst 'META-INF/LICENSE'
pickFirst 'META-INF/DEPENDENCIES'
pickFirst 'META-INF/ASL-2.0.txt'
pickFirst 'META-INF/LGPL-3.0.txt'
exclude 'META-INF/main.kotlin_module'
}
dexOptions {
preDexLibraries = false
}
}
ext {
supportLibVersion = '27.1.1'
}
dependencies {
/* ... a lot of dependencies ... */
// multi dex
implementation 'com.android.support:multidex:1.0.3'
// kotlin
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
kapt {
generateStubs = true
}
ComputedPersonData.kt file (simplified version with only the "bad" function):
class ComputedPersonData() {
var meetingsByPerson = mapOf<String, ArrayList<String>>()
fun calculateMeetingsForPerson() {
val faces: Map<String: Face?> = getFaces()
val faceToContact: Map<String: String?> = getMapping()
val peopleWithFaces = mutableMapOf<String, ArrayList<Face>>()
faces.values.forEach {
if (it != null) {
val personId = faceToContact[it.imageId] ?: ""
val list = peopleWithFaces[personId] ?: run {
peopleWithFaces[personId] = arrayListOf(it)
return#forEach
}
list.add(it)
}
}
val dictSorted = mutableMapOf<String, ArrayList<Face>>()
peopleWithFaces.forEach { id, item ->
dictSorted[id] = ArrayList(item.sortedBy { it.timestamp })
}
// the "dictSorted.mapValues{}" generates the "bad" $2 class
val dictFaceToString: Map<String, ArrayList<String>> = dictSorted.mapValues {
ArrayList(it.value.map {
it.id
}
)
}
this.meetingsByPerson = dictFaceToString
}
}
application class:
class MyApplication : MultiDexApplication()
well, after MONTHS of investigation apparently the bad lines were -
peopleWithFaces.forEach { id, item ->
dictSorted[id] = ArrayList(item.sortedBy { it.timestamp })
}
There was an issue with old android-OS (6.0.0 specific) and kotlin's decoupled for-each.
Once the problem found, the solution was easy. All we needed to do was to re-write this fun like that:
peopleWithFaces.forEach {
val id = it.key
val item = it.value
dictSorted[id] = ArrayList(item.sortedBy { it.timestamp })
}
I have some pre-build *.so files for different build flavors like arm64-v8a, armeabi-v7a, x86, x86_64, and these files are of android third party library. When I run the project all these *.so files are packaging in apk. But here my question is that how to package different *.SO files in different apks? can you please give build.gradle script for this. any help will be appreciated? Thank you. Sorry for my poor english.
my library.gradle is
apply plugin: 'com.android.library'
import com.android.builder.core.DefaultManifestParser
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
sourceSets {
main {
jni.srcDirs = []
// Prevent gradle from building native code with ndk; we have our own Makefile for it.
jniLibs.srcDirs = ['jni/libs', 'jni/loader/libs', 'private_libs/libs']
// Where generated .so files are placed.
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
// Make per-variant version code
libraryVariants.all { variant ->
def manifestParser = new DefaultManifestParser(android.sourceSets.main.manifest.srcFile)
// get the version code of each flavor
def version = manifestParser.getVersionName()
//Custom APK name
variant.outputs.all { output ->
if (outputFileName != null && outputFileName.endsWith('.aar')) {
outputFileName = "lib-${version}.aar"
}
}
}
}
class BuildNative extends Exec {}
tasks.withType(BuildNative) {
/*
Properties set for Android Studio own shell.
when you run gradlew from cli, OS shell env variables will be used
To be able to build from Android Studio, you have to set ndk.dir & sdk.dir
properties in local.properties in the root folder, like this (for example):
sdk.dir=/home/<username>/SDK/android-sdk-linux
ndk.dir=/home/<username>/SDK/android-ndk-r10b
*/
if (System.getenv('ANDROID_SDK') == null || System.getenv('ANDROID_NDK') == null) {
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
environment 'ANDROID_NDK', properties.getProperty('ndk.dir')
environment 'ANDROID_SDK', properties.getProperty('sdk.dir')
}
workingDir '..'
commandLine './compile-libvlc.sh'
}
task buildDebugARMv7(type: BuildNative) {
args('-a', "armeabi-v7a")
}
task buildDebugARM64(type: BuildNative) {
args('-a', "arm64-v8a")
}
task buildDebugx86(type: BuildNative) {
args('-a', "x86")
}
task buildDebugx86_64(type: BuildNative) {
args('-a', "x86_64")
}
task buildDebugMIPS(type: BuildNative) {
args('-a', "mips")
}
task buildDebugMIPS64(type: BuildNative) {
args('-a', "mips64")
}
task generateSources(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
clean {
// delete 'build', /*'jni/libs',*/ 'jni/obj'
}
dependencies {
api "com.android.support:support-annotations:$rootProject.ext.appCompatVersion"
api "com.android.support:support-v4:$rootProject.ext.appCompatVersion"
}
and my app.gradle is:
apply plugin: 'com.android.application'
android {
packagingOptions {
}
dexOptions {
maxProcessCount 8
javaMaxHeapSize "2g"
preDexLibraries true
keepRuntimeAnnotatedClasses false
}
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
flavorDimensions "target", "abi"
defaultConfig {
applicationId "com.example"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode rootProject.ext.versionCode
versionName rootProject.ext.versionName
vectorDrawables.useSupportLibrary true
multiDexEnabled true
}
signingConfigs {
release {
storeFile file("D:\\Keystore\\aaaaaaaa.jks")
storePassword "aaaaaaa"
keyAlias "avbbaaaaaa"
keyPassword "ababababa"
}
}
buildTypes {
release {
signingConfig null
minifyEnabled true
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
dataBinding {
enabled = true
}
productFlavors {
vanilla {
dimension "target"
versionCode = 1
}
chrome {
minSdkVersion 19
dimension "target"
versionCode = 2
}
ARMv7 {
dimension "abi"
versionCode = 4
}
x86 {
dimension "abi"
versionCode = 5
}
MIPS {
dimension "abi"
versionCode = 6
}
ARMv8 {
dimension "abi"
versionCode = 7
}
x86_64 {
dimension "abi"
versionCode = 8
}
MIPS64 {
dimension "abi"
versionCode = 9
}
}
}
Finally I found out how to do this, I got this solution from https://developer.android.com/studio/projects/gradle-external-native-builds. Hope you also get from something here.
android {
...
defaultConfig {
...
// This block is different from the one you use to link Gradle
// to your CMake or ndk-build script.
externalNativeBuild {
// For ndk-build, instead use the ndkBuild block.
cmake {
// Passes optional arguments to CMake.
arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"
// Sets a flag to enable format macro constants for the C compiler.
cFlags "-D__STDC_FORMAT_MACROS"
// Sets optional flags for the C++ compiler.
cppFlags "-fexceptions", "-frtti"
}
}
}
buildTypes {...}
productFlavors {
...
demo {
...
externalNativeBuild {
cmake {
...
// Specifies which native libraries or executables to build and package
// for this product flavor. The following tells Gradle to build only the
// "native-lib-demo" and "my-executible-demo" outputs from the linked
// CMake project. If you don't configure this property, Gradle builds all
// executables and shared object libraries that you define in your CMake
// (or ndk-build) project. However, by default, Gradle packages only the
// shared libraries in your APK.
targets "native-lib-demo",
// You need to specify this executable and its sources in your CMakeLists.txt
// using the add_executable() command. However, building executables from your
// native sources is optional, and building native libraries to package into
// your APK satisfies most project requirements.
"my-executible-demo"
}
}
}
paid {
...
externalNativeBuild {
cmake {
...
targets "native-lib-paid",
"my-executible-paid"
}
}
}
}
// Use this block to link Gradle to your CMake or ndk-build script.
externalNativeBuild {
cmake {...}
// or ndkBuild {...}
}
}
Include prebuilt native libraries
If you want Gradle to package prebuilt native libraries with your APK, modify the default source set configuration to include the directory of your prebuilt .so files, as shown below. Keep in mind, you don't need to do this to include artifacts of CMake build scripts that you link to Gradle.
android {
...
sourceSets {
main {
jniLibs.srcDirs 'imported-lib/src/', 'more-imported-libs/src/'
}
}
}
Specify ABIs
By default, Gradle builds your native library into separate .so files for the ABIs the NDK supports and packages them all into your APK. If you want Gradle to build and package only certain ABI configurations of your native libraries, you can specify them with the ndk.abiFilters flag in your module-level build.gradle file, as shown below:
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {...}
// or ndkBuild {...}
}
// Similar to other properties in the defaultConfig block,
// you can configure the ndk block for each product flavor
// in your build configuration.
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',
'arm64-v8a'
}
}
buildTypes {...}
externalNativeBuild {...}
}
By adding this script in app.gradle it works like a charm
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a','arm64-v8a'
}
Another solution would be to specify the jniLibs.srcDirs based on your flavor requirements, like this:
android {
...
sourceSets {
def flavor = getCurrentFlavor()
if (flavor == ‘device’ || flavor == ‘production’) {
jniLibs.srcDirs = ['libs']//or whatever path you have
}
...
Where getCurrentFlavor() gets your build flavor name. You can find how to do it here:
How to get current flavor in gradle
Gradle crashes with a NullpointerException when trying to debug my app in Android Studio. It works fine just to Run the app. Android Studio 2.3.3.
Here's the gradle stacktrace:
java.lang.NullPointerException
at com.android.tools.idea.run.GradleApplicationIdProvider.getTestPackageName(GradleApplicationIdProvider.java:50)
at com.android.tools.idea.run.AndroidLaunchTasksProvider.getConnectDebuggerTask(AndroidLaunchTasksProvider.java:160)
at com.android.tools.idea.run.LaunchTaskRunner.run(LaunchTaskRunner.java:79)
at com.intellij.openapi.progress.impl.CoreProgressManager$TaskRunnable.run(CoreProgressManager.java:635)
at com.intellij.openapi.progress.impl.CoreProgressManager$3.run(CoreProgressManager.java:170)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:494)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:443)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:54)
at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:155)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$1.run(ProgressManagerImpl.java:128)
at com.intellij.openapi.application.impl.ApplicationImpl$2.run(ApplicationImpl.java:307)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Here's my build.gradle inside the app folder. Some more details: This is a project with the Cocos2d-x game engine and I'm trying to get Debug for native code to work. A simple test project does work, but my own project does not.
import java.util.regex.Pattern
import com.android.build.OutputFile
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
task('increaseVersionCode') << {
println 'Grade: Increasing Version Code...'
def buildFile = file("build.gradle")
def pattern = Pattern.compile("versionCode\\s+(\\d+)")
def manifestText = buildFile.getText()
def matcher = pattern.matcher(manifestText)
matcher.find()
def versionCode = Integer.parseInt(matcher.group(1))
def manifestContent = matcher.replaceAll("versionCode " + ++versionCode)
buildFile.write(manifestContent)
}
preBuild.dependsOn increaseVersionCode
task deleteGraphicsAssets(type: Delete) {
println 'Grade: Deleting unnecessary assets...'
delete "assets/1136p"
delete "assets/2048p"
}
preBuild.dependsOn deleteGraphicsAssets
android {
// Going higher means that we have to request to write to external storage (used for UUID): https://stackoverflow.com/questions/36084959/cant-create-a-directory-on-storage-emulated-0-on-emulator
// But GameAnalytics reqires 24, let's see if it still works this way
compileSdkVersion 22
buildToolsVersion '25.0.3' // should be 25 for newer version
defaultConfig {
applicationId "com.forestringgames.apps.towerduel"
minSdkVersion 15
// Going higher means that we have to request to write to external storage (used for UUID): https://stackoverflow.com/questions/36084959/cant-create-a-directory-on-storage-emulated-0-on-emulator
// But GameAnalytics reqires 24, let's see if it still works this way
targetSdkVersion PROP_TARGET_SDK_VERSION
versionCode 1607
versionName "1.0"
// multiDexEnabled true
externalNativeBuild {
ndkBuild {
if (!project.hasProperty("PROP_NDK_MODE") || PROP_NDK_MODE.compareTo('none') != 0) {
// skip the NDK Build step if PROP_NDK_MODE is none
targets 'cocos2dcpp'
arguments 'NDK_TOOLCHAIN_VERSION=4.9'
arguments 'APP_PLATFORM=android-' + PROP_TARGET_SDK_VERSION
def module_paths = [project.file("../../FRGEngine/cocos2d").absolutePath,
project.file("../../FRGEngine/cocos2d/cocos").absolutePath,
project.file("../../FRGEngine/cocos2d/external").absolutePath]
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
// should use '/'
module_paths = module_paths.collect { it.replaceAll('\\\\', '/') }
arguments 'NDK_MODULE_PATH=' + module_paths.join(";")
} else {
arguments 'NDK_MODULE_PATH=' + module_paths.join(':')
}
arguments '-j' + Runtime.runtime.availableProcessors()
abiFilters.addAll(PROP_APP_ABI.split(':').collect { it as String })
}
}
}
}
// only added for android debugging
externalNativeBuild {
ndkBuild {
if (!project.hasProperty("PROP_NDK_MODE") || PROP_NDK_MODE.compareTo('none') != 0) {
// skip the NDK Build step if PROP_NDK_MODE is none
path "jni/Android.mk"
}
}
}
sourceSets.main {
java.srcDir "src"
res.srcDir "res"
jniLibs.srcDir "libs"
manifest.srcFile "AndroidManifest.xml"
assets.srcDir "assets"
}
splits {
abi {
enable true
reset()
include 'armeabi-v7a'
//, 'armeabi', 'armeabi-v7a', 'x86' - what about arm64? Test it with Crashlytics
universalApk false //true
}
// density {
// enable true
// reset()
// include 'mdpi', 'hdpi', 'xhdpi', 'xxhdpi', 'xxxhdpi'
// compatibleScreens 'small', 'normal', 'large', 'xlarge'
//
// }
}
signingConfigs {
release {
if (project.hasProperty("RELEASE_STORE_FILE")) {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
}
buildTypes {
release {
minifyEnabled false // Warning: is this a good idea?
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
if (project.hasProperty("RELEASE_STORE_FILE")) {
signingConfig signingConfigs.release
}
externalNativeBuild {
ndkBuild {
arguments 'NDK_DEBUG=0'
}
}
}
debug {
// debuggable true
// jniDebuggable true
externalNativeBuild {
ndkBuild {
arguments 'NDK_DEBUG=1'
}
}
}
}
}
crashlytics {
enableNdk = true
androidNdkOut = 'obj'
androidNdkLibsOut = 'libs'
}
repositories {
mavenCentral()
}
dependencies {
// compile 'com.android.support:multidex:1.0.1'
compile fileTree(include: ['*.jar'], dir: 'libs')
compile project(':libcocos2dx')
// compile project(':BaseGameUtils')
// compile 'com.android.support:multidex:1.0.0'
compile 'com.facebook.android:facebook-android-sdk:4.8.0'
// compile 'com.google.android.gms:play-services-auth:9.0.0'
// integration guide (with latest version numbers: https://fabric.io/downloads/gradle)
// Crashlytics KitminifyEnabled
compile('com.crashlytics.sdk.android:crashlytics:2.6.8#aar') {
transitive = true
}
// NDK Kit
compile('com.crashlytics.sdk.android:crashlytics-ndk:1.1.6#aar') {
transitive = true
}
// compile('com.crashlytics.sdk.android:crashlytics:2.7.0-SNAPSHOT#aar') {
// transitive = true;
// }
//
// compile('com.crashlytics.sdk.android:crashlytics-ndk:1.2.0-SNAPSHOT:debug#aar') {
// transitive = true;
// }
compile 'net.bytebuddy:byte-buddy:1.7.3'
compile 'net.bytebuddy:byte-buddy-android:1.7.3'
// compile 'com.google.firebase:firebase-auth:11.0.1'
compile 'com.google.android.gms:play-services-auth:11.0.0'
compile 'com.google.android.gms:play-services-games:11.0.0'
compile 'com.google.firebase:firebase-invites:11.0.0'
compile 'com.google.firebase:firebase-messaging:11.0.0'
compile 'com.anjlab.android.iab.v3:library:1.0.+'
compile files('Frameworks/Fmod/prebuilt/android/fmod.jar')
// // use latest version instead version number: https://github.com/GameAnalytics/GA-SDK-ANDROID
// compile 'com.gameanalytics.sdk:gameanalytics-android:3.5.0'
compile fileTree(include: ['*.jar'], dir: 'Frameworks/Jars')
//
}
apply plugin: 'com.google.gms.google-services'
Here's the project-wide build.gradle file:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
// The Fabric Gradle plugin uses an open ended version to react
// quickly to Android tooling updates
//classpath 'io.fabric.tools:gradle:1.21.5' // version number: https://twittersdk.artifactoryonline.com/twittersdk/repo/io/fabric/tools/gradle/
classpath 'io.fabric.tools:gradle:1.+'
classpath 'com.google.gms:google-services:3.1.0'
}
}
allprojects {
repositories {
jcenter()
// FABRIC PRIVATE
// maven { url 'https://s3.amazonaws.com/fabric-artifacts-private/internal-snapshots' }
// FABRIC OFFICIAL
maven { url 'https://maven.fabric.io/public' }
// maven { url 'http://maven.gameanalytics.com/release' }
}
}
Edit: I also already tried this in this order:
Rebuild Project
Clean Project
Invalidate caches / Restart
In case you are using Gradle deamon. stop it by ./gradlew --stop and start over the steps from 1 to 3
Finally & destructively close Android Studio completely and delete .gradle directory ( it's hidden ) from the root of directory of your project and then launch Android Studio again.
Close all other Android Studio Instances
Restart OSX
Make sure your NDK path is properly configured on Project Structure (File > Project Structure > SDK Location > Android NDK Location). Click "OK" and try to sync again.
I have got the following root build.gradle file:
buildscript {
repositories {
mavenCentral()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.3'
}
}
allprojects {
apply plugin: "eclipse"
apply plugin: "idea"
version = '1.0'
ext {
appName = "my_project"
gdxVersion = '1.5.4'
roboVMVersion = '1.12.0'
box2DLightsVersion = '1.3'
ashleyVersion = '1.7.0'
aiVersion = '1.8.0'
}
repositories {
mavenCentral()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven { url "https://oss.sonatype.org/content/repositories/releases/" }
}
}
project(":desktop") {
apply plugin: "java"
dependencies {
compile project(":core")
...
compile fileTree(dir: '../libs', include: '*.jar')
}
}
project(":android") {
apply plugin: "android"
configurations { natives }
dependencies {
compile project(":core")
...
compile fileTree(dir: '../libs', include: '*.jar')
}
}
project(":core") {
apply plugin: 'scala'
apply plugin: "java"
apply plugin: 'idea'
dependencies {
...
compile fileTree(dir: '../libs', include: '*.jar')
}
}
and ones for each module:
core
//apply plugin: 'scala'
apply plugin: "java"
sourceCompatibility = 1.7
[compileScala, compileTestScala, compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
sourceSets {
main {
scala.srcDirs = ['src/main/java']
java.srcDirs = []
}
test {
scala.srcDirs = ['src/test/java']
java.srcDirs = []
}
}
compileTestScala {
scalaCompileOptions.fork = true
scalaCompileOptions.forkOptions.jvmArgs = ['-XX:MaxPermSize=2048m']
scalaCompileOptions.additionalParameters = [
"-feature",
"-language:reflectiveCalls", // used for config structural typing
"-language:postfixOps"
]
}
eclipse.project {
name = appName + "-core"
}
dependencies {
}
desktop
apply plugin: "java"
sourceCompatibility = 1.7
//sourceCompatibility = JavaVersion.VERSION_1_8
//sourceSets.main.java.srcDirs = ["src/"]
sourceSets {
main {
java {
srcDirs = ["src/main/java"]
}
}
test {
java {
srcDirs = ["src/test/java"]
}
}
}
project.ext.mainClassName = "com.example.my_project.desktop.DesktopLauncher"
project.ext.assetsDir = new File("../android/assets");
task run(dependsOn: classes, type: JavaExec) {
main = project.mainClassName
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
workingDir = project.assetsDir
ignoreExitValue = true
}
task dist(type: Jar) {
from files(sourceSets.main.output.classesDir)
from files(sourceSets.main.output.resourcesDir)
from { configurations.compile.collect { zipTree(it) } }
from files(project.assetsDir);
manifest {
attributes 'Main-Class': project.mainClassName
}
}
dist.dependsOn classes
eclipse {
project {
name = appName + "-desktop"
linkedResource name: 'assets', type: '2', location: 'PARENT-1-PROJECT_LOC/android/assets'
}
}
task afterEclipseImport(description: "Post processing after project generation", group: "IDE") {
doLast {
def classpath = new XmlParser().parse(file(".classpath"))
new Node(classpath, "classpathentry", [kind: 'src', path: 'assets']);
def writer = new FileWriter(file(".classpath"))
def printer = new XmlNodePrinter(new PrintWriter(writer))
printer.setPreserveWhitespace(true)
printer.print(classpath)
}
}
dependencies {
}
android
android {
buildToolsVersion "23.0.3"
compileSdkVersion 23
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src/main/java']
resources.srcDirs = ['src/main/resources']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
instrumentTest.setRoot('tests')
}
defaultConfig {
applicationId "com.example.my_project.android"
minSdkVersion 10
targetSdkVersion 23
multiDexEnabled true
}
dexOptions {
incremental true
javaMaxHeapSize "4g"
}
lintOptions {
abortOnError false
}
}
// called every time gradle gets executed, takes the native dependencies of
// the natives configuration, and extracts them to the proper libs/ folders
// so they get packed with the APK.
task copyAndroidNatives() {
file("libs/armeabi/").mkdirs();
file("libs/armeabi-v7a/").mkdirs();
file("libs/arm64-v8a/").mkdirs();
file("libs/x86_64/").mkdirs();
file("libs/x86/").mkdirs();
configurations.natives.files.each { jar ->
def outputDir = null
if (jar.name.endsWith("natives-arm64-v8a.jar")) outputDir = file("libs/arm64-v8a")
if (jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a")
if (jar.name.endsWith("natives-armeabi.jar")) outputDir = file("libs/armeabi")
if (jar.name.endsWith("natives-x86_64.jar")) outputDir = file("libs/x86_64")
if (jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86")
if (outputDir != null) {
copy {
from zipTree(jar)
into outputDir
include "*.so"
}
}
}
}
task run(type: Exec) {
def path
def localProperties = project.file("../local.properties")
if (localProperties.exists()) {
Properties properties = new Properties()
localProperties.withInputStream { instr ->
properties.load(instr)
}
def sdkDir = properties.getProperty('sdk.dir')
if (sdkDir) {
path = sdkDir
} else {
path = "$System.env.ANDROID_HOME"
}
} else {
path = "$System.env.ANDROID_HOME"
}
def adb = path + "/platform-tools/adb"
commandLine "$adb", 'shell', 'am', 'start', '-n', 'com.mygdx.game/com.mygdx.game.AndroidLauncher'
}
// sets up the Android Eclipse project, using the old Ant based build.
eclipse {
// need to specify Java source sets explicitly, SpringSource Gradle Eclipse plugin
// ignores any nodes added in classpath.file.withXml
sourceSets {
main {
java.srcDirs "src", 'gen'
}
}
jdt {
sourceCompatibility = 1.6
targetCompatibility = 1.6
}
classpath {
plusConfigurations += [project.configurations.compile]
containers 'com.android.ide.eclipse.adt.ANDROID_FRAMEWORK', 'com.android.ide.eclipse.adt.LIBRARIES'
}
project {
name = appName + "-android"
natures 'com.android.ide.eclipse.adt.AndroidNature'
buildCommands.clear();
buildCommand "com.android.ide.eclipse.adt.ResourceManagerBuilder"
buildCommand "com.android.ide.eclipse.adt.PreCompilerBuilder"
buildCommand "org.eclipse.jdt.core.javabuilder"
buildCommand "com.android.ide.eclipse.adt.ApkBuilder"
}
}
// sets up the Android Idea project, using the old Ant based build.
idea {
module {
sourceDirs += file("src");
scopes = [COMPILE: [plus: [project.configurations.compile]]]
iml {
withXml {
def node = it.asNode()
def builder = NodeBuilder.newInstance();
builder.current = node;
builder.component(name: "FacetManager") {
facet(type: "android", name: "Android") {
configuration {
option(name: "UPDATE_PROPERTY_FILES", value: "true")
}
}
}
}
}
}
}
dependencies {
}
On my windows machine it's built having all three modules - core, desktop and android, but on linux no modules is found in project structure, except the project root folder. What could be the reason why behavior is different depending on platform type?
i'm using:
idea 2016.3,
gradle 3.2.1 (for the project default gradle wrapper),
groovy 2.4.7,
jvm 1.7.0_80
The problem was that android sdk should had been setup beforehand.