Multidex app still over 64K method limit - android

I'm facing a weird issue with multidex. I've had my app multidexed for a long time, but lately I can't build it anymore. It started after configuring Kotlin in the project.
The 'run' option in Android Studio works: the app runs successfully in my device. However, if I try the "Build APK" option or run gradlew assembleDebug, the build fails with the usual exception:
Error:The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html
Error:com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
However, multidex worked correctly before adding Kotlin. I can checkout the commit just before adding Kotlin, build the apk and check there's 3 .dex files, with a method count over 100k total.
Some key details:
Gradle 4.1, with Gradle plugin 3.0.1
Build-tools version 26.0.2
Kotlin version 1.2.0
After proguarding, the app does not need multidex, but I don't really want to proguard for debug compilation, and besides, this should be working.
Here's the complete build.gradle script:
buildscript {
repositories {
mavenCentral()
}
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'idea'
repositories {
mavenCentral()
jcenter()
maven { url "https://maven.google.com" }
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven { url 'https://jitpack.io' }
}
idea {
module {
downloadJavadoc = true
downloadSources = true
}
}
// read keystore for app signing
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = null
if (keystorePropertiesFile.exists()) {
keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
def getDate() {
def date = new Date()
def formattedDate = date.format('yyyy.MM.dd')
return formattedDate
}
def getCustomProguardFiles() {
return fileTree(dir: "proguard", include: ["*.pro"]).asList().toArray()
}
android {
compileSdkVersion 25
buildToolsVersion '26.0.2'
defaultConfig {
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
applicationId "my.app.id"
multiDexEnabled true
manifestPlaceholders = [
'appAuthRedirectScheme': 'my.app.id'
]
//TODO do not put this into release
resValue "string", "google_client_id", google_appId + ".apps.googleusercontent.com"
resValue "string", "google_auth_redirect_uri", "com.googleusercontent.apps." + google_appId + ":/oauth2redirect"
}
dexOptions {
}
dexOptions {
javaMaxHeapSize "2g"
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
signingConfigs {
release {
keyAlias keystoreProperties != null ? keystoreProperties['keyAlias'] : null
keyPassword keystoreProperties != null ? keystoreProperties['keyPassword'] : null
storeFile keystoreProperties != null ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties != null ? keystoreProperties['storePassword'] : null
}
}
lintOptions {
abortOnError false
checkReleaseBuilds false
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt')
proguardFiles getCustomProguardFiles()
testProguardFiles getDefaultProguardFile('proguard-android.txt')
testProguardFiles getCustomProguardFiles()
signingConfig signingConfigs.release
}
debug {
debuggable true
minifyEnabled false
}
}
flavorDimensions "buildType"
productFlavors {
develop {
applicationIdSuffix ""
dimension "buildType"
}
product {
dimension "buildType"
}
ci {
dimension "buildType"
}
}
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${variant.name}-${variant.versionName}.apk"
}
}
compileOptions.incremental = false
}
dependencies {
/********** DEBUGGING **********/
// Chrome debug bridge
compile 'com.facebook.stetho:stetho:1.5.0'
compile 'com.facebook.stetho:stetho-okhttp3:1.5.0'
// Memory leak debugging
// 1.5.2 held back because of a bug with gradle 3.0
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
androidTestCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
/********** SUPPORT **********/
// Multidex support
compile 'com.android.support:multidex:1.0.2'
// Support libs
compile "com.android.support:appcompat-v7:$libVersions.android.support"
compile "com.android.support:cardview-v7:$libVersions.android.support"
compile "com.android.support:customtabs:$libVersions.android.support"
compile "com.android.support:design:$libVersions.android.support"
compile "com.android.support:gridlayout-v7:$libVersions.android.support"
compile "com.android.support:palette-v7:$libVersions.android.support"
compile "com.android.support:preference-v7:$libVersions.android.support"
compile "com.android.support:recyclerview-v7:$libVersions.android.support"
compile "com.android.support:support-annotations:$libVersions.android.support"
compile "com.android.support:support-v4:$libVersions.android.support"
compile "com.android.support:support-v13:$libVersions.android.support"
// Testing dependencies
// Made explicit to avoid conflicts with other testing libs
androidTestCompile "com.android.support:appcompat-v7:$libVersions.android.support"
androidTestCompile "com.android.support:design:$libVersions.android.support"
androidTestCompile "com.android.support:recyclerview-v7:$libVersions.android.support"
androidTestCompile "com.android.support:support-annotations:$libVersions.android.support"
androidTestCompile "com.android.support:support-v4:$libVersions.android.support"
/********** TESTING **********/
// JUnit
testCompile 'junit:junit:4.12'
// Mockito
testCompile "org.mockito:mockito-core:2.8.47"
// Support testing
androidTestCompile 'com.android.support.test.espresso:espresso-contrib:3.0.0'
androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.0'
androidTestCompile 'com.android.support.test:rules:1.0.0'
androidTestCompile 'com.android.support.test:runner:1.0.0'
/********** UTILITIES **********/
// HTML parsing
compile 'org.jsoup:jsoup:1.10.2'
// Event bus
compile 'org.greenrobot:eventbus:3.0.0'
// FHIR
compile 'ca.uhn.hapi.fhir:hapi-fhir-android:3.1.0'
compile 'ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3:3.1.0'
// Jobs
compile 'com.evernote:android-job:1.1.11'
// JSON serializing-deserializing
compile 'com.google.code.gson:gson:2.8.1'
// JWT validation
compile 'com.nimbusds:nimbus-jose-jwt:4.41.1'
// Lang utilities
// Used for Levenshtein distance, etc
compile 'org.apache.commons:commons-lang3:3.6'
compile 'org.apache.commons:commons-text:1.1'
// OpenID authentication
compile 'net.openid:appauth:0.7.0'
// QR code scanning
compile 'com.google.zxing:core:3.3.0'
compile 'com.journeyapps:zxing-android-embedded:3.5.0#aar'
// Play Services (for Firebase InstanceID)
compile 'com.google.android.gms:play-services-auth:11.6.0'
// Recurrence processing
compile 'org.dmfs:lib-recur:0.10'
// REST services
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-scalars:2.1.0'
// SQLite ORM
compile 'com.j256.ormlite:ormlite-android:5.0'
// Time and date handling
compile 'com.fatboyindustrial.gson-jodatime-serialisers:gson-jodatime-serialisers:1.6.0'
compile 'joda-time:joda-time:2.9.7'
// View/resource binding
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
compile 'com.jakewharton:butterknife:8.8.1'
/********** VIEWS AND VIEW UTILITIES **********/
// About page with libraries
compile('com.mikepenz:aboutlibraries:5.2.5#aar') {
transitive = true
}
// Calendar views
compile 'com.roomorama:caldroid:3.0.1'
compile 'com.squareup:android-times-square:1.6.4#aar'
// Circular progress "pie" view
// Used for pill picker
compile 'com.github.filippudak.progresspieview:library:1.0.4'
// Dialogs with material style
compile 'com.github.javiersantos:MaterialStyledDialogs:2.0'
// Floating Action Button
compile 'com.getbase:floatingactionbutton:1.9.0'
// GIF ImageView
compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.3'
// Icons
compile 'com.mikepenz:community-material-typeface:1.9.32.2#aar'
compile 'com.mikepenz:google-material-typeface:2.1.2.1#aar'
compile 'com.mikepenz:iconics-core:2.7.1#aar'
// Image loading
compile 'com.squareup.picasso:picasso:2.5.2'
// Intro slides
compile 'com.heinrichreimersoftware:material-intro:1.5.8'
// Material style utilities
compile('com.mikepenz:materialize:0.2.7#aar') {
transitive = true
}
// Picker DialogFragments
compile 'com.code-troopers.betterpickers:library:3.1.0'
// Round image view
compile 'com.makeramen:roundedimageview:1.5.0'
// Tab strip
compile 'com.astuetz:pagerslidingtabstrip:1.0.1'
// Sliding left drawer
compile('com.mikepenz:materialdrawer:4.4.1#aar') {
transitive = true
}
// Recyclerview adapters
compile('com.mikepenz:fastadapter:2.1.5#aar') {
transitive = true
}
compile 'com.mikepenz:fastadapter-commons:2.1.0#aar'
compile 'com.mikepenz:fastadapter-extensions:2.1.0#aar'
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// Schedule step-by-step building
compile 'com.stepstone.stepper:material-stepper:3.3.0'
compile 'com.wdullaer:materialdatetimepicker:3.2.2'
compile 'com.shawnlin:number-picker:2.4.4'
}
apply plugin: 'com.google.gms.google-services'
And the build.gradle of the project:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.2.0'
repositories {
jcenter()
maven { url "https://maven.google.com" }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:3.0.0'
}
ext {
libVersions = [
android: [
support: '25.4.0'
]
]
}
}

It turned out to be a problem with the way I was including HAPI-FHIR. It's a really big library with tons of dependencies, and it probably was collapsing the main dexfile.
In the end, I solved it by replacing:
// FHIR
compile 'ca.uhn.hapi.fhir:hapi-fhir-android:3.1.0'
compile 'ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3:3.1.0'
with:
// FHIR
compile 'ca.uhn.hapi.fhir:hapi-fhir-base:3.1.0#jar'
compile 'ca.uhn.hapi.fhir:hapi-fhir-utilities:3.1.0#jar'
compile 'ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3:3.1.0#jar'
compile 'commons-io:commons-io:2.5'
compile 'org.slf4j:slf4j-api:1.7.25#jar'
commons-io and slf4j are runtime dependencies of HAPI, and when using #jar those dependencies aren't downloaded, so they need to be explicitly declared.
Note: this particular configuration is only valid for my use case, as HAPI has more runtime dependencies, which would need to be added manually as well in case they're needed.

Related

Android aar include jar dependency resources folder

Hello
While developing an Android AAR module, I encounter the following problem
My AAR module has a few jar dependencies, some of them have resources folder with error localized error messages. For some reason when I create the module AAR I noticed that Android build process exclude the resources folder from the jar dependency. The dependencies folder is an essential part since otherwise the error details are not found.
If something could shed light on the issue, I tried to create additional resources folder under main/resources//messages.properties but it didn't help.
Any help will be appreciated
here is my gradle file
apply plugin: 'com.android.library'
apply plugin: 'jacoco'
allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
}
}
buildscript {
repositories {
jcenter()
google()
mavenCentral()
}
dependencies {
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.2'
classpath 'com.android.tools.build:gradle:3.2.1'
}
}
android {
compileSdkVersion 27
buildToolsVersion '26.0.3'
configurations {
javadocDeps
}
defaultConfig {
minSdkVersion 21
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
testCoverageEnabled false
}
}
testOptions {
unitTests.all {
jacoco {
includeNoLocationClasses = true
}
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false}
showStandardStreams = true
}
}
unitTests.returnDefaultValues = true
}
lintOptions {
abortOnError false
}
sourceSets {
androidTest {
...
}
test {
}
}
}
//assembleDebug.dependsOn(copyResDirectoryToClasses)
dependencies {
releaseCompile fileTree(include: ['*.jar'], dir: 'libs')
provided 'com.android.support:appcompat-v7:27.1.1'
provided 'org.jetbrains:annotations:16.0.3'
provided 'com.google.code.findbugs:annotations:3.0.1'
provided 'org.codehaus.sonar-plugins:sonar-ant-task:2.2'
provided 'org.jetbrains:annotations-java5:15.0'
provided 'com.google.android:annotations:4.1.1.4'
provided 'com.squareup.okhttp3:okhttp:3.9.1'
provided 'com.squareup.okhttp3:okhttp-urlconnection:3.9.1'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'org.mockito:mockito-core:1.9.5'
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestCompile files('../sdkSample/lib/qa_utils.jar')
androidTestCompile 'com.google.android:annotations:4.1.1.4'
javadocDeps 'com.android.support:appcompat-v7:27.1.1'
javadocDeps 'com.squareup.okhttp3:okhttp:3.9.1'
javadocDeps 'com.squareup.okhttp:okhttp-urlconnection:3.9.1'
javadocDeps 'com.google.code.findbugs:annotations:3.0.1'
javadocDeps group: 'org.mozilla', name: 'rhino', version: '1.7.7.1'
javadocDeps group: 'org.jetbrains', name: 'annotations', version: '16.0.3'
testCompile files('../sdkSample/lib/qa_utils.jar')
testCompile 'junit:junit:4.12'
testCompile 'org.json:json:20171018'
testCompile 'com.google.android:annotations:4.1.1.4'
testCompile 'org.testng:testng:6.13.1'
testCompile 'com.squareup.okhttp3:okhttp:3.9.1'
testCompile 'com.squareup.okhttp3:okhttp-urlconnection:3.9.1'
testCompile 'org.robolectric:robolectric:3.8'
androidTestCompile 'com.squareup.okhttp3:okhttp:3.9.1'
androidTestCompile 'com.squareup.okhttp3:okhttp-urlconnection:3.9.1'
testCompile 'org.khronos:opengl-api:gl1.1-android-2.1_r1'
}
gradle.taskGraph.whenReady {
gradle.taskGraph.allTasks.each {
if(it.project == 'sdkSample') {
it.onlyIf { false }
}
}
}
//ignore all test failures - is done temporary, the final solution is test categorization
project.gradle.taskGraph.whenReady {
-> project.tasks.findAll { it.name =~ /connected.+AndroidTest/ ||
it.name == "testDebugUnitTest" ||
it.name =="testReleaseUnitTest" }.each {
it.ignoreFailures = true
}
}
You need to use api instead of provided. You can find more info from here.
As i know aar cant have transitive dependencies. You may try export fat aar or you can give it a try to
implementation 'your.package:your_artifact:your_version' {transitive = true}
PS: Dont use type #aar
Also known as flatDir, because flatDir dependencies DOES NOT resolve transitives)
implementation 'your.package:your_artifact:your_version#aar' {transitive = true}
On the otherhand, you need to convert your project to maven standards. So that, you need a pom.xml file which points transitive dependencies under dependencies tag.
As you experienced jar files cant have resource files either. If you dont need to resource files, just export jar by executing createFullJarRelease task.
If you have to use .aar, you can add other dependencies that library uses in consumer.

Aapt2 error : Using ormlite and while running OrmLiteConfigUtil getting below error after upgrading to Android studio 3 and gradle 3

Normally i am able to build my project but whenever there is a database change i need to run OrmLiteConfigUtil and after running it i get error as below. it never succeeds. I tried exploring other question and found below solution but still it doesn't works.
I tried disabling Aapt2 by putting android.enableAapt2=false in gradle properties file.
Information:Gradle: Executing tasks: [:library:assembleDebug, :app:assembleDebug]
Information:Gradle: BUILD FAILED in 58s
Information:Modules "library", "app" were fully rebuilt due to project configuration/dependencies changes
Information:21-02-2018 05:09 PM - Compilation completed with 5 errors and 0 warnings in 1m 8s 524ms
Error:Gradle: failed to create directory 'D:\Working_folder\Fieldez_5.5.6.2\app\build\generated\source\r\debug\com\fieldez\mobile'.
Error:Gradle: java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
Error:Gradle: java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
Error:Gradle: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
Error:Gradle: Execution failed for task ':app:processDebugResources'.
> Failed to execute aapt
My Project level gradle code
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
}
}
allprojects {
repositories {
jcenter()
}
}
App level gradle file
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
apply plugin: 'let'
repositories {
mavenCentral()
jcenter()
maven {
url "https://oss.sonatype.org/content/repositories/snapshots"
}
maven {
url "https://jitpack.io"
}
/* maven {
url "https://mint.splunk.com/gradle/"
}*/
maven { url 'https://maven.fabric.io/public' }
maven { url "https://raw.githubusercontent.com/smilefam/SendBird-SDK-Android/master/" }
google()
}
buildscript {
repositories {
jcenter()
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'com.canelmas.let:let-plugin:0.1.10'
classpath 'io.fabric.tools:gradle:1.+'
}
}
android {
compileSdkVersion 'Google Inc.:Google APIs:23'
buildToolsVersion '26.0.2'
defaultConfig {
vectorDrawables.useSupportLibrary = true
applicationId "com.fieldez.mobile"
minSdkVersion 16
targetSdkVersion 23
multiDexEnabled true
dexOptions {
javaMaxHeapSize "4g"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
release {
shrinkResources true
minifyEnabled true
zipAlignEnabled true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
// uncomment the below 4 lines to test release build
debug {
// minifyEnabled true
// shrinkResources true
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// zipAlignEnabled true
}
}
useLibrary 'org.apache.http.legacy'
/*productFlavors {
//configstring.xml debugMode == true
debugMode {
versionName '3.5.4'
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent,
output.outputFile.name.replace("app-debugMode-release", "FieldEZ Product" + "-${variant.versionName}")
)
}
}
}
//configstring.xml debugMode == false
releaseMode {
versionName '3.5.4'
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent,
output.outputFile.name.replace("app-releaseMode-release", "FieldEZ Product Release" + "-${variant.versionName}")
)
}
}
}
}*/
}
dependencies {
implementation fileTree(dir: 'libs', include: '*.jar')
// Play Services
implementation 'com.google.android.gms:play-services-maps:9.0.2'
implementation 'com.google.android.gms:play-services-location:9.0.2'
implementation 'com.google.android.gms:play-services-gcm:9.0.2'
//Support Libraries
implementation 'com.android.support:appcompat-v7:24.0.0'
implementation 'com.android.support:design:24.0.0'
implementation 'com.android.support:recyclerview-v7:24.0.0'
implementation 'com.android.support:cardview-v7:24.0.0'
implementation 'com.android.support:support-v4:24.0.0'
//ORMLite DB
implementation 'com.j256.ormlite:ormlite-core:4.48'
implementation 'com.j256.ormlite:ormlite-android:4.48'
// apache http
implementation 'org.apache.httpcomponents:httpmime:4.2.5'
// For Date and Time Pickers
implementation 'com.wdullaer:materialdatetimepicker:2.2.0'
//For Images
implementation 'com.squareup.picasso:picasso:2.5.2'
// RecyclerView Animations
implementation 'jp.wasabeef:recyclerview-animators:2.2.1'
// JSON Parsing
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'com.google.android.gms:play-services-appindexing:9.0.2'
// For crash reports
// compile "com.splunk.mint:mint:5.0.0"
// Calendar
implementation 'com.github.nikhilpanju:material-calendarview:-SNAPSHOT'
implementation project(':library')
//okhttp
// compile 'com.squareup.okhttp3:okhttp:3.3.1'
//Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.1.0'
//RecyclerViewEnhanced
implementation 'com.nikhilpanju.recyclerviewenhanced:recyclerviewenhanced:1.1.0'
//writeToPDF
// compile 'com.itextpdf:itextg:5.5.10'
//multidex
implementation 'com.android.support:multidex:1.0.1'
//Mixpanel for analytics
// compile "com.mixpanel.android:mixpanel-android:4.+"
//apteligent for crash reports
//compile 'com.crittercism:crittercism-android-agent:+'
implementation('com.crashlytics.sdk.android:crashlytics:2.6.8#aar') {
transitive = true;
}
// RecyclerViewHeader2
implementation 'com.bartoszlipinski:recyclerviewheader2:2.0.1'
// FabtoDialog
implementation 'konifar:fab-transformation:1.0.0'
// seeing database
// debugCompile 'com.amitshekhar.android:debug-db:1.0.1'
// SendBird Chat API
implementation 'com.sendbird.sdk:sendbird-android-sdk:3.0.26'
// sendbird using external libraries
// External libraries
implementation 'com.github.bumptech.glide:glide:3.7.0'
implementation 'org.jsoup:jsoup:1.10.2'
// Butterknife
// compile 'com.jakewharton:butterknife:8.8.1'
// annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
// FAB Menu (Temporarily using my PR for this library until it's merged)
//compile 'com.github.clans:fab:1.6.4'
implementation 'com.github.nikhilpanju:FloatingActionButton:-SNAPSHOT'
// RXJava for Concurrency and Multithreading
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex:rxjava:1.1.0'
}
Which is my project level gradle.propeties file in these or i dont have it ?

./Gradlew Build is taking 2 hours and 40 minutes - Is there any room for improvement?

The app that we are working on is not very large - most of it is an empty application that gets filled in from various endpoints (server side), but we currently have 18 separate flavors of the app that get built.
The issue is, there will be 78 flavors of the application built and if the build time is linear, we are looking at about 11 hours per ./gradlew build request.
Im not well versed in Gradle at all and I was hoping you guys could help me find some problem areas that might be able to improve our build times
Here is the build.gradle:
apply plugin: 'com.android.application'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
apply plugin: 'io.fabric'
apply from: '../jacoco.gradle'
apply from: '../flavors.gradle'
apply from: '../autoTasks.gradle'
ext {
applicationName = 'OurApp'
supportLibVersion = '25.3.0'
playServicesVersion = '9.6.1'
}
android {
signingConfigs {
debug {
keyAlias 'key'
keyPassword 'pass'
storeFile file('../file.keystore')
storePassword 'pass'
}
release {
keyAlias 'key'
keyPassword 'pass'
storeFile file('../file.jks')
storePassword 'pass'
}
}
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
minSdkVersion 16
targetSdkVersion 25
vectorDrawables.useSupportLibrary true
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
multiDexEnabled true
}
dataBinding {
enabled true
}
lintOptions {
abortOnError false
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
buildConfigField 'String', 'DFP_NETWORK_ID', '"id"'
buildConfigField 'String', 'YOUTUBE_API_KEY', '"ourkey"'
}
debug {
signingConfig signingConfigs.debug
testCoverageEnabled = true
buildConfigField 'String', 'DFP_NETWORK_ID', '"id"'
buildConfigField 'String', 'YOUTUBE_API_KEY', '"anotherKey"'
}
debuggable.initWith(buildTypes.debug)
debuggable {
testCoverageEnabled = false
}
}
dexOptions {
javaMaxHeapSize "4g"
}
applicationVariants.all { variant ->
if (variant.buildType.name == 'release') {
createZipProguardTask(variant);
}
updateApkName(variant);
}
}
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
annotationProcessor 'com.bluelinelabs:logansquare-compiler:1.3.7'
annotationProcessor 'com.squareup:javapoet:1.8.0'
annotationProcessor 'com.google.dagger:dagger-compiler:2.7'
compile "com.android.support:appcompat-v7:${supportLibVersion}"
compile "com.android.support:design:${supportLibVersion}"
compile "com.android.support:recyclerview-v7:${supportLibVersion}"
compile "com.android.support:support-v13:${supportLibVersion}"
compile "com.android.support:percent:${supportLibVersion}"
compile "com.android.support:preference-v14:${supportLibVersion}"
compile "com.google.android.gms:play-services-gcm:${playServicesVersion}"
compile "com.google.android.gms:play-services-maps:${playServicesVersion}"
compile "com.google.firebase:firebase-core:${playServicesVersion}"
compile "com.google.firebase:firebase-messaging:${playServicesVersion}"
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.roughike:bottom-bar:2.2.0'
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.l4digital.rxloader:rxloader:2.0.1'
compile 'com.bluelinelabs:logansquare:1.3.7'
compile 'com.github.aurae.retrofit2:converter-logansquare:1.4.1'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
compile 'com.google.dagger:dagger:2.7'
compile 'com.facebook.stetho:stetho:1.4.2'
compile 'com.facebook.stetho:stetho-okhttp3:1.4.2'
compile('com.crashlytics.sdk.android:crashlytics:2.6.5#aar') {
transitive = true
}
compile(name:'googlemediaframework-release', ext:'aar')
compile "com.google.android.gms:play-services-ads:${playServicesVersion}"
compile "com.google.android.gms:play-services-analytics:${playServicesVersion}"
compile 'com.flurry.android:ads:6.2.0'
compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.6.0'
compile 'com.google.android.exoplayer:exoplayer:r1.5.14'
compile 'com.android.support:multidex:1.0.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.5.0'
debugCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
debuggableCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
androidTestCompile 'junit:junit:4.12'
androidTestCompile 'com.squareup.okhttp3:okhttp:3.5.0'
androidTestCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestCompile('com.android.support.test:rules:0.5') {
exclude module: 'support-annotations'
}
androidTestCompile (name:'cloudtestingscreenshotter_lib', ext:'aar')
androidTestCompile('com.android.support.test:runner:0.5') {
exclude module: 'support-annotations'
}
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2') {
exclude module: 'support-annotations'
}
compile(name:'MapSDK', ext:'aar')
compile('com.twitter.sdk.android:twitter:2.3.2#aar') {
transitive = true;
}
}
def createZipProguardTask(variant) {
def prefix = project.ext.applicationName;
if (project.hasProperty('buildNumber')) {
prefix += '-' + project.getProperties().get('buildNumber');
}
def taskName = variant.flavorName.substring(0, 1).toUpperCase() + variant.flavorName.substring(1);
task("zipProguard${taskName}", type: Zip) {
archiveName = "${prefix}-${variant.flavorName}-proguard.zip";
from "build/outputs/mapping/${variant.flavorName}/release"
destinationDir file('build/outputs/mapping')
}
}
def updateApkName(variant) {
def prefix = project.ext.applicationName;
if (project.hasProperty('buildNumber')) {
prefix += '-' + project.getProperties().get('buildNumber');
}
variant.outputs.each { output ->
def fileName = output.outputFile.name.replace('app', prefix);
def outputFile = new File(output.outputFile.parent.toString(), fileName.toString());
output.outputFile = outputFile;
}
}
Here is what we have in the gradle properties:
org.gradle.jvmargs=-Xmx4608M -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.parallel=true
org.gradle.daemon=true
Any input would be greatly appreciated - like I said, I'm not well versed in gradle at all, so I'm open to anything.
Thank you in advance
I'm sure you figured something out by now, but just for future googlers -
Android Studio gradle takes too long to build improved the speed of my gradle build drastically. It suggests enabling Offline work in Android Studio by going to file>settings>build, execution, deployment>gradle and checking the "Offline work" option.

androidTestCompile not working in Android Studio 2.1.2

I followed the instruction here to add an instrumentation test, but unfortunately Android Studio complains about the classes from the test runner package (com.android.support.test:runner:0.5) or test rules or espresso-core (cannot find symbol). If I change the dependency type from androidTestCompile to compile, the errors disappear. I created an instrumentation run config, and currently that run config is selected.
EDIT:
Here is our Gradle build file:
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'com.neenbedankt.android-apt'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'realm-android'
apply plugin: 'pmd'
buildscript {
repositories {
jcenter()
maven { url 'https://maven.fabric.io/public' }
mavenCentral()
maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local' }
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
classpath 'com.google.gms:google-services:2.0.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath 'me.tatarka:gradle-retrolambda:3.2.5'
classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
classpath 'io.realm:realm-gradle-plugin:1.0.0'
classpath 'io.fabric.tools:gradle:1.21.6'
}
configurations.classpath.exclude group: 'com.android.tools.external.lombok'
}
repositories {
jcenter()
mavenCentral()
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local' }
maven { url 'https://repo.commonsware.com.s3.amazonaws.com' }
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
compile 'com.android.support:multidex:1.0.1'
// compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:24.0.0'
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:support-v13:24.0.0'
compile 'com.android.support:recyclerview-v7:24.0.0'
compile 'com.android.support:design:24.0.0'
compile 'com.android.support:percent:24.0.0'
compile 'com.google.android.gms:play-services-auth:9.0.2'
compile 'com.google.android.gms:play-services-gcm:9.0.2'
compile "com.mixpanel.android:mixpanel-android:4.8.6"
compile 'com.squareup.retrofit2:retrofit:2.0.1'
compile 'com.squareup.retrofit2:converter-gson:2.0.1'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.1'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
compile 'com.squareup:otto:1.3.8'
compile 'com.squareup.dagger:dagger:1.2.2'
apt 'com.squareup.dagger:dagger-compiler:1.2.2'
compile('com.facebook.android:facebook-android-sdk:4.13.1') {
exclude module: 'bolts-android'
exclude module: 'bolts-applinks'
exclude module: 'bolts-tasks'
}
compile 'com.facebook.fresco:fresco:0.11.0'
compile 'me.relex:photodraweeview:1.0.0'
compile 'com.jakewharton.rxrelay:rxrelay:1.0.0'
compile 'com.jakewharton:butterknife:8.1.0'
apt 'com.jakewharton:butterknife-compiler:8.1.0'
compile 'com.jakewharton.timber:timber:4.0.1'
compile 'javax.annotation:javax.annotation-api:1.2'
compile 'com.cloudinary:cloudinary-android:1.2.2:'
compile 'com.soundcloud.android:android-crop:1.0.1#aar'
compile 'com.rockerhieu.emojicon:library:1.3.3'
compile 'io.reactivex:rxandroid:1.2.0'
compile 'com.trello:rxlifecycle:0.5.0'
compile 'com.trello:rxlifecycle-components:0.5.0'
compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'
compile 'com.jakewharton.rxbinding:rxbinding-recyclerview-v7:0.4.0'
compile 'com.jakewharton.rxbinding:rxbinding-support-v4:0.4.0'
compile 'com.jakewharton.rxbinding:rxbinding-design:0.4.0'
compile 'com.github.hotchemi:permissionsdispatcher:2.1.1'
apt 'com.github.hotchemi:permissionsdispatcher-processor:2.1.1'
compile 'net.sourceforge.streamsupport:streamsupport:1.4.3'
compile('com.crashlytics.sdk.android:crashlytics:2.5.5#aar') {
transitive = true;
}
androidTestCompile 'com.android.support.test:rules:0.5'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'junit:junit:4.12'
}
android {
// General configuration goes here
compileSdkVersion 23
buildToolsVersion '23.0.3'
defaultConfig {
def buildNumber = computeVersionCode()
applicationId 'com.xxx.xxx'
minSdkVersion 19
targetSdkVersion 23
versionCode = buildNumber
versionName '0.2.6'
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner "android.test.InstrumentationTestRunner"
}
dexOptions {
incremental true
javaMaxHeapSize "6g"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
signingConfigs {
debug {
storeFile rootProject.file('debug.keystore')
storePassword 'xxx'
keyAlias 'xxx'
keyPassword 'xxx'
}
beta {
String password = getKeyStorePassword()
println("password::$password")
if (password) {
storeFile file("beta_release.keystore")
storePassword xxx
keyAlias "xxx"
keyPassword xxx
} else {
println "Environment variable BETA_KEYSTORE_PASSWORD needs to be set"
}
}
}
buildTypes {
localDebug {
minifyEnabled false
debuggable true;
signingConfig signingConfigs.debug
buildConfigField "String", "BACKEND_ADDRESS", "\"http://xxx.xxx.dev/\""
buildConfigField "boolean", "MYVAR2", "false"
buildConfigField "String", "MYVAR3", "\"value\""
resValue "string", "BUILD_TYPE_DISPLAY", "Debug(Local)"
applicationIdSuffix ".debug"
}
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
exclude 'META-INF/services/javax.annotation.processing.Processor'
}
lintOptions {
abortOnError true
}
splits {
abi {
enable true
reset()
include 'x86', 'x86_64', 'arm64-v8a', 'armeabi-v7a', 'armeabi'
universalApk false
}
}
}
task pmd(type: Pmd) {
ruleSetFiles = files("${project.rootDir}/pmd-ruleset.xml")
ignoreFailures = false
ruleSets = []
source 'src'
include '**/*.java'
exclude '**/gen/**'
reports {
xml.enabled = false
html.enabled = true
xml {
destination "$project.buildDir/reports/pmd/pmd.xml"
}
html {
destination "$project.buildDir/reports/pmd/pmd.html"
}
}
}
def computeVersionCode() {
def buildNumber = System.getenv('BUILD_NUMBER')
if (buildNumber == null || buildNumber.isEmpty()) {
println "No BUILD_NUMBER in environment, using 1 as revision"
return 1
}
buildNumber = buildNumber.toInteger()
println "New revision is ${buildNumber}"
return buildNumber
}
configurations.all {
resolutionStrategy {
force 'com.android.support:support-annotations:24.0.0'
force 'com.android.support:support-v4:24.0.0'
force 'com.android.support:appcompat-v7:24.0.0'
force 'com.android.support:design:24.0.0'
force 'com.android.support:recyclerview-v7:24.0.0'
}
}
I've spent about a day on this myself and finally figured it out. This is an Android Studio feature - termed a feature, but I'd consider it a bug.
To get instrumentation tests working, you need to set your Build Variants to the following:
Test Artifact: Android Instrumentation Tests
Build Variant: debug
See here for more details
I personally think is makes no sense; it's not like you're using androidTestCompileDebug, and running gradle <app_name>:dependencies repeatedly shows pulling in androidTestCompile dependencies, regardless of the build variant. But for some reason, they only resolve in debug.
I hope this helps.

Databinding fails with NoSuchMethodError

After updating to gradle 2.10 every time when I try to assemble debug build of the app I get the NoSuchMethodError exception. Here is the relevant part of the build log:
java.lang.RuntimeException: failure, see logs for details.
cannot generate view binders java.lang.NoSuchMethodError: com.google.common.base.Strings.isNullOrEmpty(Ljava/lang/String;)Z
at android.databinding.tool.util.StringUtils.capitalize(StringUtils.java:57)
at android.databinding.tool.util.ParserHelper.toClassName(ParserHelper.java:23)
at android.databinding.tool.store.ResourceBundle$LayoutFileBundle.getFullBindingClass(ResourceBundle.java:551)
at android.databinding.tool.store.ResourceBundle$LayoutFileBundle.getBindingClassPackage(ResourceBundle.java:541)
at android.databinding.tool.CompilerChef.pushClassesToAnalyzer(CompilerChef.java:124)
at android.databinding.tool.CompilerChef.createChef(CompilerChef.java:73)
at android.databinding.annotationprocessor.ProcessExpressions.writeResourceBundle(ProcessExpressions.java:148)
at android.databinding.annotationprocessor.ProcessExpressions.onHandleStep(ProcessExpressions.java:82)
at android.databinding.annotationprocessor.ProcessDataBinding$ProcessingStep.runStep(ProcessDataBinding.java:154)
at android.databinding.annotationprocessor.ProcessDataBinding$ProcessingStep.access$000(ProcessDataBinding.java:139)
at android.databinding.annotationprocessor.ProcessDataBinding.process(ProcessDataBinding.java:66)
As you can see Method com.google.common.base.Strings.isNullOrEmpty can't be found.
Some specifics
I use Retrolambda 3.2.5 and Java 8. There are no other extra plugins.
Build plugin version: com.android.tools.build:gradle:2.0.0
Build tools version: 23.0.3
OS: OS X
build.gradle looks like this. I altered it slightly to not expose some private stuff, but problem is still there.
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0'
classpath 'me.tatarka:gradle-retrolambda:3.2.3'
}
}
apply plugin: 'com.android.application'
apply plugin: 'me.tatarka.retrolambda'
project.version = '1.0.0'
afterEvaluate {
tasks.matching {
it.name.startsWith('dex')
}.each { dx ->
if (dx.additionalParameters == null) {
dx.additionalParameters = []
}
dx.additionalParameters += "--set-max-idx-number=50000" // default 60000
}
}
def googleApiKey = "key goes here"
def appVersionCode = 1
def appVersionName = project.version + "." + appVersionCode
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
minSdkVersion 15
targetSdkVersion 23
manifestPlaceholders = [googleApiKey : googleApiKey,
appVersionCode: appVersionCode,
appVersionName: appVersionName]
multiDexEnabled true
ndk {
abiFilters "armeabi", "armeabi-v7a"
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg'
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(
output.outputFile.parent,
"App-${project.version}-${appVersionCode}.apk"
)
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
flavorDimensions "multidex", "leakcanary"
productFlavors {
withLeakCanary {
dimension "leakcanary"
}
withoutLeakCanary {
dimension "leakcanary"
}
develDex {
dimension "multidex"
minSdkVersion 21
targetSdkVersion 23
}
prodDex {
dimension "multidex"
minSdkVersion 15
targetSdkVersion 23
}
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/DEPENDENCIES'
}
lintOptions {
abortOnError false
}
sourceSets {
main {
jniLibs.srcDir 'build/jniLibs'
}
}
dexOptions {
javaMaxHeapSize "4g"
}
dataBinding {
enabled = true
}
}
task copyNativeLibs(type: Copy) {
from(new File(buildDir, 'intermediates/exploded-aar/')) {
include '**/*.so'
exclude '**/lib-detector.so'
}
into new File(buildDir, 'jniLibs')
eachFile { details ->
def pathSplit = details.path.split('/')
details.path = pathSplit[pathSplit.length - 2] + '/' + pathSplit[pathSplit.length - 1]
}
includeEmptyDirs = false
}
tasks.withType(JavaCompile) { javaCompileTask -> javaCompileTask.dependsOn copyNativeLibs }
clean.dependsOn 'cleanCopyNativeLibs'
dependencies {
testCompile 'junit:junit:4.11'
testCompile 'org.robolectric:robolectric:3.0'
testCompile 'org.robolectric:shadows-multidex:3.0'
testCompile('org.robolectric:shadows-httpclient:3.0') {
exclude module: 'httpcore'
exclude module: 'commons-codec'
}
testCompile 'org.powermock:powermock-module-junit4:1.5.2'
testCompile 'org.powermock:powermock-api-mockito:1.5.2'
testCompile 'org.roboguice:roboguice:3.0.1'
compile 'com.parse.bolts:bolts-android:1.2.1'
compile fileTree(dir: 'libs', include: 'Parse-*.jar')
compile 'com.google.android.gms:play-services-drive:7.8.0'
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.android.support:multidex:1.0.1'
compile 'com.android.support:support-annotations:23.0.1'
compile 'com.android.support:support-v4:23.0.1'
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:recyclerview-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
compile 'org.roboguice:roboguice:3.0.1'
provided 'org.roboguice:roboblender:3.0.1'
compile('com.google.inject.extensions:guice-assistedinject:3.0') {
exclude group: 'com.google.inject', module: 'guice'
}
compile 'commons-io:commons-io:2.4'
compile 'commons-lang:commons-lang:2.6'
compile 'com.intellij:annotations:12.0'
compile 'com.google.zxing:core:3.2.1'
compile 'com.google.zxing:android-core:3.2.1'
compile 'com.google.android.gms:play-services-base:7.8.0'
compile 'com.google.android.gms:play-services-location:7.8.0'
compile 'com.google.android.gms:play-services-maps:7.8.0'
compile 'com.google.android.gms:play-services-analytics:7.8.0'
compile 'com.amazon:in-app-purchasing:2.0.1'
compile 'com.googlecode.libphonenumber:libphonenumber:7.0.7'
withLeakCanaryCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
compile 'com.google.android.gms:play-services-ads:7.8.0'
compile 'io.reactivex:rxandroid:1.0.1'
compile 'io.reactivex:rxjava:1.0.14'
}
Question
Did anyone else had the same problem? How to fix it? If you need some extra information, please let me know in comments.
Have you tried the new patch on jitpack of simular issue #134 clean-build, there seemed to be something wrong with gradle import ordering you can try it with :
repositories {
maven { url "https://jitpack.io" }
}
dependencies {
classpath 'com.github.denis-itskovich:gradle-retrolambda:3.2.3-fix-134'
}
It looks like there is an error with a plugin after upgrading the Android Studio.
If you go in : <Android Studio Dir>/plugins/android/lib/builder-model-x.x.x.jar you may find 2 .jars. Try to delete the old version .jar and keep the new one and also clean and rebuild the project.
if the above does not work try this:
Change the version of Objectify library in the build.gradle file of your backend to 4.0b to 5.0.3 or higher if it exists.
This is may sound irrelevant but objectify 4.0b library has same classes with same package name which are present in appengine sdk like com.google.common.base.Strings.isNullOrEmpty.
when you deploy the app backend the appengine classes are overridden by objectify classes and hence when you try to call some method it is throwing error.
This is solved in objectify 5.0.+
Hope it helps as it helped me solving this issue.

Categories

Resources