Shrinking Your Dependencies

Your module’s build.gradle file will have a dependencies closure listing all its dependencies. Lines with implementation, kapt, and api will be the dominant ones, and those reflect code and resources that are packaged into your APK. By contrast, things like testImplementation and androidTestImplementation only affect test code and will not be part of your APK.

Your app may have few or lots of dependencies:

    exclude 'META-INF/AL2.0'
    exclude 'META-INF/LGPL2.1'
  }
}

dependencies {
  implementation 'androidx.core:core-ktx:1.6.0'
  implementation 'androidx.appcompat:appcompat:1.3.1'
  implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
  implementation "androidx.recyclerview:recyclerview:1.2.1"
  implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
  implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
  implementation 'com.google.android.material:material:1.4.0'
  implementation "io.insert-koin:koin-android:3.1.2"
  implementation "androidx.room:room-runtime:2.3.0"
  implementation "androidx.room:room-ktx:2.3.0"
  kapt "androidx.room:room-compiler:2.3.0"
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
  testImplementation 'junit:junit:4.13.2'
  testImplementation "org.mockito:mockito-inline:3.12.1"
  testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
  testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.1'
  androidTestImplementation 'androidx.test.ext:junit:1.1.3'
  androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
  androidTestImplementation "androidx.arch.core:core-testing:2.1.0"
  androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.1'
}

This module has nearly 20 dependencies that will go into the APK… and this is a fairly trivial app.

Plus, each dependency can pull in others, via what is called “transitive dependencies”. For example, the androidx.room:room-ktx dependency in that listing:

If you fold open the “External Libraries” section of your project in the Android Studio explorer tree, you will see all the libraries that this project pulls in. This list will include test dependencies, so not everything in the list will go into your APK. But it also shows you the results of resolving all the transitive dependencies.

So… do you need all of that? Perhaps not.

Unfortunately, there is no good way to determine what you could remove. Perhaps by reviewing the dependencies list, you will recognize some that were from past experiments and are no longer needed.

The only real way to know if you can skip the dependency is to comment it out (e.g., using //), then see if your project builds and your tests run. If they do, presumably you can now remove the commented-out dependency entirely. If, on the other hand, there was some build failure, that means you are still referencing things from that dependency.

If very little of your app refers to things from that dependency, though, perhaps you could find another way of implementing that functionality that would let you remove the dependency. For example, HelloWorld uses ConstraintLayout, from the androidx.constraintlayout set of dependencies. However, ConstraintLayout is not needed for that simple UI — you could accomplish the same look with something else, such as a FrameLayout. Rewriting that layout resource to avoid ConstraintLayout would allow you to remove the androidx.constraintlayout dependencies, and that would reduce the size of the HelloWorld APK.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.