Kotlin’s @Keep Annotation: Keeping Your Code Safe and Sound

Sandeep Kella
ProAndroidDev

--

Hey there, Kotlin enthusiasts! Today, let’s dive into the magical world of Kotlin annotations, specifically the @Keep annotation. We'll explore what it does, why it's important, and how to use it, all while having a bit of fun with everyday analogies. Ready? Let’s get started!

Imagine Your Code is a Party

Think of your code as a bustling house party. You’ve invited all your friends (classes, functions, properties), and everyone’s having a great time. But here’s the thing: there’s a bouncer at the door — the code optimizer — whose job is to kick out any guests who don’t seem to be having any fun (i.e., aren’t being used). This is where the @Keep annotation comes into play.

What is @Keep?

The @Keep annotation in Kotlin is like a VIP badge for your code. When you slap @Keep on a class, function, or property, you're telling the optimizer, "Hey, this one's important! Don’t kick them out, even if they seem quiet."

Why Do We Need @Keep?

Sometimes, certain parts of your code might not be directly called from within your project. For example, you might be using reflection, or certain methods might be used by external libraries. Without @Keep, the optimizer might see these parts as unnecessary and remove them, leading to unexpected behavior or bugs.

How to Use @Keep

Using @Keep is as simple as putting on a badge. Here’s how you can do it:

Step 1: Import the Annotation

First, make sure you import the @Keep annotation:

import androidx.annotation.Keep

Step 2: Annotate Your Code

Next, place the @Keep annotation above the classes, functions, or properties you want to protect.

import androidx.annotation.Keep

@Keep
class VIPPartyMember {
fun importantFunction() {
println("I'm crucial for this party!")
}
}

class Party {
@Keep
fun serveDrinks() {
println("Serving drinks to everyone!")
}

@Keep
val snacks = "Chips and salsa"
}

Breaking It Down: Everyday Analogy

Let’s say you’re hosting a party (your app), and you’ve hired a bouncer (the optimizer) to make sure the party doesn’t get overcrowded. However, you’ve got a few friends who are really important to the party’s success but tend to hang out in the background.

Here’s what happens:

  • Without @Keep: The bouncer looks around and sees your quiet friend (the importantFunction method) just hanging out in the corner. Thinking they're not contributing, the bouncer kicks them out.
  • With @Keep: You hand your quiet friend a VIP badge (@Keep). Now, when the bouncer sees the badge, they know this friend is crucial, even if they're not always in the spotlight, and lets them stay.

Real-World Scenario

Consider an app that relies on reflection to call certain methods. Reflection might not show up in the static analysis the optimizer performs, so it might think the methods are unused and remove them. By using @Keep, you ensure these methods are retained, preventing any runtime crashes.

import androidx.annotation.Keep

@Keep
fun reflectedMethod() {
println("This method is called via reflection.")
}

fun main() {
// Assume this is called via reflection in the real app
reflectedMethod()
}

Wrapping Up

In a nutshell, the @Keep annotation is your way of telling the optimizer to leave certain parts of your code alone, ensuring everything runs smoothly. It's like handing out VIP badges at your party to make sure your key guests stay, even if they aren’t always in the spotlight.

So next time you’re writing Kotlin code and have some important but quiet members in your codebase, remember to give them a VIP badge with @Keep. Your code (and your future self) will thank you!

And there you have it! A fun, easy-to-understand explanation of Kotlin’s @Keep annotation. Now go forth and annotate with confidence! 🎉

--

--

Android developer @PhonePe, writes about Android development and productivity.