Bird
Raised Fist0
Android Kotlinmobile~20 mins

ProGuard and R8 optimization in Android Kotlin - Mini App: Build & Ship

Choose your learning style10 modes available
Build: ProGuardR8OptimizationScreen
This screen demonstrates how to enable and configure ProGuard and R8 optimizations in an Android Kotlin project. It shows a simple UI with a toggle to enable minification and a button to display the current optimization status.
Target UI
-------------------------
| ProGuard & R8 Setup   |
|-----------------------|
| Minify Enabled: [ ]   |
|                       |
| [Check Status]         |
-------------------------
Add a Switch to enable or disable code minification (ProGuard/R8).
Add a Button labeled 'Check Status' that shows a Toast with current minify status.
Use Kotlin and Android best practices.
Show how to configure build.gradle for enabling minification.
Starter Code
Android Kotlin
package com.example.proguardr8

import android.os.Bundle
import android.widget.Button
import android.widget.Switch
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity

class ProGuardR8OptimizationScreen : AppCompatActivity() {
    private lateinit var minifySwitch: Switch
    private lateinit var checkStatusButton: Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_proguard_r8_optimization)

        minifySwitch = findViewById(R.id.switch_minify)
        checkStatusButton = findViewById(R.id.button_check_status)

        // TODO: Add listener to minifySwitch to update build config
        // TODO: Add click listener to checkStatusButton to show minify status
    }
}
Task 1
Task 2
Task 3
Solution
Android Kotlin
package com.example.proguardr8

import android.os.Bundle
import android.widget.Button
import android.widget.Switch
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity

class ProGuardR8OptimizationScreen : AppCompatActivity() {
    private lateinit var minifySwitch: Switch
    private lateinit var checkStatusButton: Button
    private var isMinifyEnabled = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_proguard_r8_optimization)

        minifySwitch = findViewById(R.id.switch_minify)
        checkStatusButton = findViewById(R.id.button_check_status)

        minifySwitch.setOnCheckedChangeListener { _, isChecked ->
            isMinifyEnabled = isChecked
            Toast.makeText(this, if (isChecked) "Minify Enabled" else "Minify Disabled", Toast.LENGTH_SHORT).show()
        }

        checkStatusButton.setOnClickListener {
            val status = if (isMinifyEnabled) "Minification is ON" else "Minification is OFF"
            Toast.makeText(this, status, Toast.LENGTH_SHORT).show()
        }
    }
}

/*
In your module-level build.gradle file, add or update the following inside the android block:

android {
    buildTypes {
        release {
            minifyEnabled true // or false to disable
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

This enables R8/ProGuard minification and optimization for release builds.
*/

This screen uses a Switch to simulate enabling or disabling code minification, which is controlled in the build.gradle file for real projects. The Button shows the current minify status using a Toast message.

The key part of enabling ProGuard and R8 optimization is in the build.gradle file where minifyEnabled true turns on code shrinking and obfuscation. The app UI here helps beginners understand the concept interactively.

Final Result
Completed Screen
-------------------------
| ProGuard & R8 Setup   |
|-----------------------|
| Minify Enabled: [x]   |
|                       |
| [Check Status]         |
-------------------------
Tapping the switch toggles minify enabled state and shows a Toast 'Minify Enabled' or 'Minify Disabled'.
Tapping 'Check Status' button shows a Toast with current minify status: 'Minification is ON' or 'Minification is OFF'.
Stretch Goal
Add a TextView that displays the current build.gradle minifyEnabled setting dynamically.
💡 Hint
Use a ViewModel or saved state to keep track of minifyEnabled and update the TextView when the switch changes.

Practice

(1/5)
1. What is the main purpose of enabling minifyEnabled true in your Android app's release build?
easy
A. To automatically generate UI layouts
B. To increase the app's debug information for easier troubleshooting
C. To disable ProGuard and R8 optimizations
D. To shrink and optimize the app code by removing unused parts

Solution

  1. Step 1: Understand the role of minifyEnabled

    Setting minifyEnabled true activates code shrinking and optimization tools like ProGuard and R8.
  2. Step 2: Identify the effect on app code

    These tools remove unused code and optimize the remaining code to reduce app size and improve performance.
  3. Final Answer:

    To shrink and optimize the app code by removing unused parts -> Option D
  4. Quick Check:

    minifyEnabled true = shrink and optimize [OK]
Hint: minifyEnabled true means code shrinking is ON [OK]
Common Mistakes:
  • Thinking it increases debug info instead of reducing code
  • Confusing minifyEnabled with disabling optimizations
  • Assuming it generates UI layouts automatically
2. Which of the following is the correct way to specify a ProGuard rules file in your build.gradle for release builds?
easy
A. proguardFiles 'proguard-rules.txt'
B. proguardFiles 'proguard-android-optimize.txt', getDefaultProguardFile('proguard-rules.pro')
C. proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
D. minifyEnabled false

Solution

  1. Step 1: Recall the standard syntax for ProGuard files

    The correct syntax uses getDefaultProguardFile for the default file and then adds custom rules.
  2. Step 2: Match the correct order and file names

    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' correctly calls getDefaultProguardFile('proguard-android-optimize.txt') and then adds 'proguard-rules.pro'.
  3. Final Answer:

    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' -> Option C
  4. Quick Check:

    Correct ProGuard file syntax = proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' [OK]
Hint: Default file uses getDefaultProguardFile() [OK]
Common Mistakes:
  • Swapping file names or forgetting getDefaultProguardFile()
  • Setting minifyEnabled false disables ProGuard
  • Using wrong file extensions like .txt instead of .pro
3. Given this ProGuard rule:
-keep class com.example.MyClass { *; }

What will happen to MyClass during code shrinking?
medium
A. It will be kept intact with all its members
B. It will be removed if unused
C. Only its public methods will be kept
D. It will be renamed but removed if unused

Solution

  1. Step 1: Understand the -keep rule

    The -keep directive tells ProGuard to keep the specified class and its members without removing or renaming them.
  2. Step 2: Analyze the rule syntax

    The rule -keep class com.example.MyClass { *; } means keep the entire class and all its members intact.
  3. Final Answer:

    It will be kept intact with all its members -> Option A
  4. Quick Check:

    -keep class = keep all members [OK]
Hint: -keep means keep class and members intact [OK]
Common Mistakes:
  • Thinking -keep removes unused classes
  • Assuming only public methods are kept
  • Confusing renaming with removal
4. You enabled minifyEnabled true but your app crashes at runtime due to missing classes. What is the most likely cause?
medium
A. You set minifyEnabled false by mistake
B. You forgot to add -keep rules for classes used via reflection
C. You used the wrong ProGuard file name in build.gradle
D. You disabled R8 in your project

Solution

  1. Step 1: Identify the cause of missing classes

    When code shrinking removes classes used only by reflection, runtime crashes occur.
  2. Step 2: Understand the role of -keep rules

    Adding -keep rules for such classes prevents their removal during shrinking.
  3. Final Answer:

    You forgot to add -keep rules for classes used via reflection -> Option B
  4. Quick Check:

    Missing classes after shrinking = missing -keep rules [OK]
Hint: Add -keep rules for reflection-used classes [OK]
Common Mistakes:
  • Assuming minifyEnabled false causes missing classes
  • Confusing file name errors with missing classes
  • Thinking disabling R8 causes missing classes
5. You want to keep all classes in the package com.example.models but allow R8 to rename their members to reduce size. Which ProGuard rule should you use?
hard
A. -keepnames class com.example.models.**
B. -keepclassmembers class com.example.models.** { *; }
C. -keep class com.example.models.** { *; }
D. -keepclassmembernames class com.example.models.** { *; }

Solution

  1. Step 1: Understand the difference between -keep and -keepnames

    -keep prevents removal and renaming; -keepnames prevents renaming but allows removal.
  2. Step 2: Match the requirement

    You want to keep classes but allow member renaming, so -keepnames on classes is correct.
  3. Final Answer:

    -keepnames class com.example.models.** -> Option A
  4. Quick Check:

    Keep classes but rename members = -keepnames [OK]
Hint: -keepnames keeps class names but allows member renaming [OK]
Common Mistakes:
  • Using -keep which prevents renaming
  • Confusing -keepclassmembers with -keepnames
  • Assuming -keepclassmembernames keeps classes
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard