Documenting Kotlin Code for Android Using KDoc and Dokka
Learn how to use KDoc to document your Kotlin code and generate beautiful-looking documentation pages using Dokka. By Rajdeep Singh.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Documenting Kotlin Code for Android Using KDoc and Dokka
25 mins
- Getting Started
- Understanding the Project Structure
- Making a Case for Documentation
- Going Beyond Code Comments
- Learning From Examples
- Introducing KDoc
- Defining Block Tags
- Documenting Modules and Packages
- Introducing Dokka
- Integrating Dokka
- Generating Documentation
- Customizing Dokka
- Adding External Documentation
- Customizing Member Visibility
- Customizing Module and Package Pages
- Using Custom Assets
- Where to Go From Here?
Customizing Dokka
The first thing you’ll customize is the output directory for module-level HTML documentation.
If you remember the gradle tasks from before, dokkaHtml
is the task responsible for generating HTML documentation for each individual module.
Open the root-level build.gradle file and replace TODO:8
with following:
tasks.named("dokkaHtml") {
outputDirectory.set(file("$rootProject.name-$project.name-dokka"))
}
This updates the task to use a different output directory for each module. So, Dokka will use notktx-app-dokka, notktx-core-dokka and notktx-utilities-dokka for the respective modules.
But now, calling the clean
task in gradle won’t delete the documentation directories because they aren’t under the build directory anymore.
To fix that, replace the TODO:9
line with the snippet shown below:
task cleanDokkaModuleDocs() {
subprojects {
delete file("$rootProject.name-$project.name-dokka")
}
}
To invoke this task automatically when calling ./gradlew clean
, update the clean
task to depend on dokkaHtmlMultiModule
. The task should look like this:
task clean(type: Delete, dependsOn: cleanDokkaModuleDocs) {
delete rootProject.buildDir
}
This adds a gradle task that goes through all the subprojects and deletes the custom documentation directories. Run ./gradlew dokkaHtml dokkaHtmlMultiModule
to generate documentation in the newly defined custom directory structure.
Whenever you want to delete those generated documentation directories, you need to run ./gradlew clean
in the terminal. It will call cleanDokkaModuleDocs
itself for you.
Adding External Documentation
There’s a minor problem in the documentation you generated in the last section. If you open the ImageLoaders.kt and look at the KDoc comment for loadImageFromUrl
, you’ll see this snippet:
* @see Picasso
This should add a link to Picasso
class in the See also section of loadImageFromUrl
‘s documentation.
But if you open the multimodule documentation in a browser and click loadImageFromUrl in the utilities
package, you’ll see it doesn’t provide a clickable link. Instead, it shows a text with the package name of Picasso.
Dokka needs to know the location of JavaDoc of any third-party library for this external linking to work. To do that, open the root-level build.gradle and replace TODO:10
with following snippet:
tasks.named("dokkaHtmlPartial") {
dokkaSourceSets {
named("main") {
externalDocumentationLink {
url.set(new URL("https://square.github.io/picasso/2.x/picasso/"))
}
externalDocumentationLink {
url.set(new URL("https://bumptech.github.io/glide/javadocs/4120/"))
}
}
}
}
One thing to keep in mind is that the external link has to end with a /
.
Add the external documentation links for dokkaHtml
task too by adding the below snippet in tasks.named("dokkaHtml")
:
dokkaSourceSets {
named("main") {
externalDocumentationLink {
url.set(new URL("https://square.github.io/picasso/2.x/picasso/"))
}
externalDocumentationLink {
url.set(new URL("https://bumptech.github.io/glide/javadocs/4120/"))
}
}
}
This adds the links to Picasso’s and Glide’s documentation pages. loadRoundImageFromUrl
uses Glide to load images.
Run ./gradlew clean dokkaHtmlMultiModule
in the terminal to generate the documentation again. You’ll see that Dokka adds the link to the Picasso
class in the documentation now. How it works under the hood goes beyond the scope of this article.
Dokka generates the See also section for @see
block tag. It’s useful for cases when you want to point readers to other functions or classes to get a better understanding of the current one.
Say that you decide to deprecate loadImageFromUrl
and add a new function, loadImageFromUrlV2
, that uses Glide
under the hood to load images instead of Picasso
to get consistent with loadRoundImageFromUrl
.
You’ll need to do three things:
- Add the new function and its documentation describing the library version in which it was added.
- Add a deprecation tag for
loadImageFromUrl
and a way to point users to its replacement function. - Update the library version.
Open ImageLoaders.kt and replace TODO:11
with the following snippet:
/**
* An extension function on [ImageView] receiver to load an image from some remote url.
*
* This function uses <b>Glide</b> which is a 3rd party library to handle all the networking and
* caching side of things. Glide handles the loading w.r.t. the lifecycle of the view for you.
*
* <b>Sample Usage</b>
*
* ```
* yourImageView.loadImageFromUrlV2(url = "https://someurl.com/someImage")
* ```
*
* @receiver [ImageView]
* @param url Url to load image from
* @since v1.0.2
* @see Glide
*/
fun ImageView.loadImageFromUrlV2(url: String) {
Glide.with(this).load(url).centerCrop().into(this)
}
To deprecate the existing function, you need to add Deprecated
annotation above its definition. And, to point users to the replacement function, you need to add @see loadImageFromUrlV2
in the KDoc comment.
After doing the above changes, loadImageFromUrl
will look something like this:
// Truncated code above
* @param url Url to load image from
* @see Picasso
* @see loadImageFromUrlV2
*/
@Deprecated(message = "Moving to Glide", replaceWith = ReplaceWith("loadImageFromUrlV2"),
level = DeprecationLevel.WARNING)
fun ImageView.loadImageFromUrl(url: String) {
// Truncated code below
Finally, you need to update the library version. Open publish.gradle file and change LIB_VERSION
variable to "1.0.2"
.
Run ./gradlew clean dokkaHtmlMultiModule
and you’ll see documentation pages updated to these:
Customizing Member Visibility
The next thing you’ll do is stop Dokka from showing all the methods and properties of parent classes in MainActivity.
Select the MainActivity tab in the generated docs, and you’ll see a lot of functions and properties listed there that you didn’t define. Those are from the parent classes and hide the functions and properties you actually care about.
Dokka provides a flag to hide the members of the parent class you didn’t explicitly override.
Open the root-level build.gradle file and add suppressInheritedMembers.set(true)
in both dokkaHtml
and dokkaHtmlPartial
tasks. Tasks should look like this:
// Truncated code above
tasks.named("dokkaHtml") {
outputDirectory.set(file("$rootProject.name-$project.name-dokka"))
suppressInheritedMembers.set(true)
// Truncated code
tasks.named("dokkaHtmlPartial") {
suppressInheritedMembers.set(true)
// Truncated code below
Run ./gradlew clean dokkaHtmlMultiModule
to see the changes:
The functions and properties from the parent classes are gone, but the overridden onCreate
method and other private methods and properties aren’t showing up either.
Dokka hides non public members by default. To show non-public properties and methods, you need to add includeNonPublic.set(true)
in the main source set in the dokkaSourceSets
block. It should look like this:
dokkaSourceSets {
named("main") {
includeNonPublic.set(true)
externalDocumentationLink {
url.set(new URL("https://square.github.io/picasso/2.x/picasso/"))
}
externalDocumentationLink {
url.set(new URL("https://bumptech.github.io/glide/javadocs/4120/"))
}
}
}
If you want any property, method or class to not show up in the documentation, you can use @suppress
tag. Open MainActivity.kt and replace TODO:15
with the snippet below:
/**
* @suppress
*/
Run ./gradlew clean dokkaHtmlMultiModule
to see the changes: