Adding Library Modules
When you create a new Android Studio project, by default you get a single module named app
. For many simple projects, that is all that you need.
The Sampler
and SamplerJ
projects have lots of modules. All but one of these are application modules, ones that create Android apps. Ordinarily, each of these apps might be in a separate project as an app
module — they are combined into a single project for your convenience:
- You only have to check out a single Git repository
- You can easily flip from one sample to another in a single IDE window
However, one module in the Sampler
Kotlin project, named Utilities
, is unlike the other modules. Utilities
is a library module, not an application module. A library module does not build an Android app. Instead, it is just a container for code, resources, and assets that can be used by other modules.
In this chapter, we will explore briefly what the value is of library modules and how to use library modules that somebody created. Later in the book, we will see how to create library modules of your own.
Reasons for Library Modules
There are lots of reasons why you might want to have one or more library modules in a project. Here are just a few of them.
Reuse Across App Modules
The reason for the Utilities
library module in this project is to reuse code across multiple other modules. You can define classes once in the library and reuse them in the other modules, rather than having to maintain a bunch of parallel copies of that class in those other modules.
Utilities
contains a single class — ViewBindingFragment
— that we will use in several sample apps over the course of the rest of the book. We will see what ViewBindingFragment
is in the next chapter.
It is also possible to publish a library in a way that it can be used by apps implemented in other projects. Each of the implementation
lines that we see in our module’s build.gradle
file represents some library that somebody else wrote and published.
Reduce Build Time
Suppose we have an app
module that depends on 7 library modules. The app
module represents 30% of the total code of the project, and each of the library modules contributes an additional 10%. In this case:
- Changing code in
app
usually only requires building things in theapp
module itself, not the libraries - Changing code in a library would require building the library, plus building any modules that depend upon that library, such as the
app
module
Making a change to the app, therefore, might require building 30-40% of the code. If all of the code were in the app
module, with no libraries, making a change to the app would require building 100% of the code.
In reality, the story here is a lot more complex, as build times depend on what you are changing (Java/Kotlin code? resources? manifest entries?) as well as the module organization. Smaller projects will not gain much build speed from this sort of module separation. Large projects, though, might build a lot faster, enough to make the headache of organizing the code this way be worthwhile.
Define Internal APIs
Normally, in Kotlin, everything is public
unless you expressly declare it to be private
. In a single-module project, those are your only two visibility options.
However, in a multi-module project, you can take advantage of Kotlin’s internal
visibility modifier. internal
says:
- Treat it as
public
with respect to other code in this module - Treat it as
private
with respect to code in other modules that depend upon this module
Hence, you can use internal
to better define the “contracts” between portions of code, to better delineate what is the “API surface” that others can use and what is internal implementation that should not be used. When everything resides in a single module, internal
works the same as public
and has no value.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.