diff --git a/app/src/main/kotlin/com/skydoves/myapplication/ExampleRecompositionTracking.kt b/app/src/main/kotlin/com/skydoves/myapplication/ExampleRecompositionTracking.kt
index 2586aef..e151a19 100644
--- a/app/src/main/kotlin/com/skydoves/myapplication/ExampleRecompositionTracking.kt
+++ b/app/src/main/kotlin/com/skydoves/myapplication/ExampleRecompositionTracking.kt
@@ -43,7 +43,7 @@ import com.skydoves.myapplication.models.UnstableUser
* 1. Add @TraceRecomposition annotation to your composable
* 2. Build the project (tracking code is automatically injected by the compiler)
* 3. Enable logging in your Application class:
- * LoggerProvider.setEnabled(BuildConfig.DEBUG)
+ * ComposeStabilityAnalyzer.setEnabled(BuildConfig.DEBUG)
* 4. Run your app and check Logcat for "Recomposition" tag
*/
@Composable
@@ -252,7 +252,7 @@ fun RecompositionDemo() {
* class MyApp : Application() {
* override fun onCreate() {
* super.onCreate()
- * LoggerProvider.setEnabled(BuildConfig.DEBUG)
+ * ComposeStabilityAnalyzer.setEnabled(BuildConfig.DEBUG)
* }
* }
* ```
diff --git a/compose-stability-analyzer-idea/CHANGELOG.md b/compose-stability-analyzer-idea/CHANGELOG.md
index db6a351..5e5cf8b 100644
--- a/compose-stability-analyzer-idea/CHANGELOG.md
+++ b/compose-stability-analyzer-idea/CHANGELOG.md
@@ -6,6 +6,19 @@ All notable changes to the IntelliJ IDEA plugin will be documented in this file.
---
+## [0.5.2] - 2025-11-13
+
+### Fixed
+- **Fixed APK size increase in release builds** (Issue #39)
+ - ProGuard rules were keeping entire stability-runtime package unnecessarily
+ - Optimized consumer-rules.pro to only keep classes used by compiler-injected code
+ - Now only keeps `RecompositionTracker` methods (constructor, trackParameter, logIfThresholdMet)
+ - Logger classes only kept if explicitly used via `ComposeStabilityAnalyzer.setLogger()`
+ - Compile-time classes (`StabilityInfo`, `ComposableInfo`, `ParameterInfo`) now removed by R8
+ - This fix dramatically reduces release APK size when using the plugin
+
+---
+
## [0.5.1] - 2025-11-10
### Added
diff --git a/compose-stability-analyzer-idea/build.gradle.kts b/compose-stability-analyzer-idea/build.gradle.kts
index 8e3d5bf..71fd1d0 100644
--- a/compose-stability-analyzer-idea/build.gradle.kts
+++ b/compose-stability-analyzer-idea/build.gradle.kts
@@ -71,6 +71,12 @@ intellijPlatform {
""".trimIndent()
changeNotes = """
+ 0.5.2
+
+ - CRITICAL FIX: Resolved APK size bloat in release builds (Issue #39)
+ - ProGuard rules optimized - only keeps classes actually used by compiler-injected code
+ - Dramatically reduced release APK size when using the plugin
+
0.5.1
- Added wasmJs target support - Runtime module now supports WebAssembly JavaScript for Compose Multiplatform web apps (Issue #32)
diff --git a/gradle.properties b/gradle.properties
index a709db7..4fe8cd3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -51,7 +51,7 @@ kotlin.mpp.androidGradlePluginCompatibility.nowarn=true
# Maven publishing
GROUP=com.github.skydoves
-VERSION_NAME=0.5.1
+VERSION_NAME=0.5.2
POM_URL=https://github.com/skydoves/compose-stability-analyzer/
POM_SCM_URL=https://github.com/skydoves/compose-stability-analyzer/
diff --git a/stability-gradle/src/main/kotlin/com/skydoves/compose/stability/gradle/StabilityAnalyzerGradlePlugin.kt b/stability-gradle/src/main/kotlin/com/skydoves/compose/stability/gradle/StabilityAnalyzerGradlePlugin.kt
index 5a03546..9e0f6c6 100644
--- a/stability-gradle/src/main/kotlin/com/skydoves/compose/stability/gradle/StabilityAnalyzerGradlePlugin.kt
+++ b/stability-gradle/src/main/kotlin/com/skydoves/compose/stability/gradle/StabilityAnalyzerGradlePlugin.kt
@@ -45,7 +45,7 @@ public class StabilityAnalyzerGradlePlugin : KotlinCompilerPluginSupportPlugin {
// This version should match the version in gradle.properties
// Update this when bumping the library version
- private const val VERSION = "0.5.1"
+ private const val VERSION = "0.5.2"
// Compiler option keys
private const val OPTION_ENABLED = "enabled"
diff --git a/stability-runtime/consumer-rules.pro b/stability-runtime/consumer-rules.pro
index 20563b6..270e5da 100644
--- a/stability-runtime/consumer-rules.pro
+++ b/stability-runtime/consumer-rules.pro
@@ -1,26 +1,27 @@
-# Keep all classes and functions annotated with @TraceRecomposition
-# These are transformed by the compiler plugin and must not be obfuscated
--keep @com.skydoves.compose.stability.runtime.TraceRecomposition class * { *; }
--keep class * {
- @com.skydoves.compose.stability.runtime.TraceRecomposition *;
-}
--keepclassmembers class * {
- @com.skydoves.compose.stability.runtime.TraceRecomposition *;
-}
-
-# Keep the TraceRecomposition annotation itself
+# Keep annotations (used at compile-time, small overhead to keep)
-keep @interface com.skydoves.compose.stability.runtime.TraceRecomposition
-
-# Keep all stability runtime annotations
-keep @interface com.skydoves.compose.stability.runtime.StableForAnalysis
--keep @interface com.skydoves.compose.stability.runtime.SkipStabilityAnalysis
-keep @interface com.skydoves.compose.stability.runtime.IgnoreStabilityReport
-# Keep RecompositionTracker and related classes used by injected code
--keep class com.skydoves.compose.stability.runtime.RecompositionTracker { *; }
--keep class com.skydoves.compose.stability.runtime.** { *; }
+# Keep ONLY RecompositionTracker - used by compiler-injected code
+# The compiler injects calls to: constructor, trackParameter(), logIfThresholdMet()
+-keep class com.skydoves.compose.stability.runtime.RecompositionTracker {
+ public (java.lang.String, java.lang.String, int);
+ public ;
+}
+
+# Keep public API for users who explicitly call ComposeStabilityAnalyzer.setLogger()
+# ComposeStabilityAnalyzer is a Kotlin object (singleton), methods are accessed via INSTANCE
+# These are only kept if referenced (R8 will remove if unused)
+-keep,allowobfuscation class com.skydoves.compose.stability.runtime.ComposeStabilityAnalyzer {
+ public ;
+}
+-keep,allowobfuscation interface com.skydoves.compose.stability.runtime.RecompositionLogger {
+ public ;
+}
+-keep,allowobfuscation class com.skydoves.compose.stability.runtime.RecompositionEvent { *; }
+-keep,allowobfuscation class com.skydoves.compose.stability.runtime.ParameterChange { *; }
-# Keep all stability info data classes
--keep class com.skydoves.compose.stability.runtime.StabilityInfo { *; }
--keep class com.skydoves.compose.stability.runtime.ComposableInfo { *; }
--keep class com.skydoves.compose.stability.runtime.ParameterInfo { *; }
+# Note: StabilityInfo/ComposableInfo/ParameterInfo are only used for JSON generation
+# at compile-time. They don't need to be kept in the runtime APK.
+# R8 will automatically remove them if unused.
diff --git a/stability-runtime/src/commonMain/kotlin/com/skydoves/compose/stability/runtime/RecompositionLogger.kt b/stability-runtime/src/commonMain/kotlin/com/skydoves/compose/stability/runtime/RecompositionLogger.kt
index 926053b..65508c4 100644
--- a/stability-runtime/src/commonMain/kotlin/com/skydoves/compose/stability/runtime/RecompositionLogger.kt
+++ b/stability-runtime/src/commonMain/kotlin/com/skydoves/compose/stability/runtime/RecompositionLogger.kt
@@ -35,7 +35,7 @@ import kotlin.concurrent.Volatile
* }
*
* // In Application.onCreate()
- * LoggerProvider.setLogger(FirebaseRecompositionLogger())
+ * ComposeStabilityAnalyzer.setLogger(FirebaseRecompositionLogger())
* ```
*/
public interface RecompositionLogger {
@@ -110,13 +110,13 @@ public expect class DefaultRecompositionLogger() : RecompositionLogger {
* Usage:
* ```kotlin
* // Set custom logger (typically in Application.onCreate() or MainActivity)
- * LoggerProvider.setLogger(MyCustomLogger())
+ * ComposeStabilityAnalyzer.setLogger(MyCustomLogger())
*
* // Enable/disable logging
- * LoggerProvider.setEnabled(BuildConfig.DEBUG)
+ * ComposeStabilityAnalyzer.setEnabled(BuildConfig.DEBUG)
*
* // Get current logger
- * val logger = LoggerProvider.getLogger()
+ * val logger = ComposeStabilityAnalyzer.getLogger()
* ```
*/
public object ComposeStabilityAnalyzer {
@@ -155,7 +155,7 @@ public object ComposeStabilityAnalyzer {
*
* Use this to disable logging in production builds:
* ```kotlin
- * LoggerProvider.setEnabled(BuildConfig.DEBUG)
+ * ComposeStabilityAnalyzer.setEnabled(BuildConfig.DEBUG)
* ```
*
* @param enabled Whether logging should be enabled.
diff --git a/stability-runtime/src/commonTest/kotlin/com/skydoves/compose/stability/runtime/LoggerProviderTest.kt b/stability-runtime/src/commonTest/kotlin/com/skydoves/compose/stability/runtime/ComposeStabilityAnalyzerTest.kt
similarity index 90%
rename from stability-runtime/src/commonTest/kotlin/com/skydoves/compose/stability/runtime/LoggerProviderTest.kt
rename to stability-runtime/src/commonTest/kotlin/com/skydoves/compose/stability/runtime/ComposeStabilityAnalyzerTest.kt
index 52d3873..cb95329 100644
--- a/stability-runtime/src/commonTest/kotlin/com/skydoves/compose/stability/runtime/LoggerProviderTest.kt
+++ b/stability-runtime/src/commonTest/kotlin/com/skydoves/compose/stability/runtime/ComposeStabilityAnalyzerTest.kt
@@ -23,7 +23,7 @@ import kotlin.test.assertFalse
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
-class LoggerProviderTest {
+class ComposeStabilityAnalyzerTest {
private val defaultLogger = DefaultRecompositionLogger()
@@ -40,13 +40,13 @@ class LoggerProviderTest {
}
@Test
- fun testLoggerProvider_defaultLogger() {
+ fun testComposeStabilityAnalyzer_defaultLogger() {
val logger = ComposeStabilityAnalyzer.getLogger()
assertNotNull(logger)
}
@Test
- fun testLoggerProvider_setCustomLogger() {
+ fun testComposeStabilityAnalyzer_setCustomLogger() {
val customLogger = TestLogger()
ComposeStabilityAnalyzer.setLogger(customLogger)
@@ -55,12 +55,12 @@ class LoggerProviderTest {
}
@Test
- fun testLoggerProvider_enabledByDefault() {
+ fun testComposeStabilityAnalyzer_enabledByDefault() {
assertTrue(ComposeStabilityAnalyzer.isEnabled())
}
@Test
- fun testLoggerProvider_setEnabled() {
+ fun testComposeStabilityAnalyzer_setEnabled() {
ComposeStabilityAnalyzer.setEnabled(false)
assertFalse(ComposeStabilityAnalyzer.isEnabled())
@@ -69,7 +69,7 @@ class LoggerProviderTest {
}
@Test
- fun testLoggerProvider_logEvent_whenEnabled() {
+ fun testComposeStabilityAnalyzer_logEvent_whenEnabled() {
val customLogger = TestLogger()
ComposeStabilityAnalyzer.setLogger(customLogger)
ComposeStabilityAnalyzer.setEnabled(true)
@@ -82,7 +82,7 @@ class LoggerProviderTest {
}
@Test
- fun testLoggerProvider_logEvent_whenDisabled() {
+ fun testComposeStabilityAnalyzer_logEvent_whenDisabled() {
val customLogger = TestLogger()
ComposeStabilityAnalyzer.setLogger(customLogger)
ComposeStabilityAnalyzer.setEnabled(false)
@@ -94,7 +94,7 @@ class LoggerProviderTest {
}
@Test
- fun testLoggerProvider_multipleEvents() {
+ fun testComposeStabilityAnalyzer_multipleEvents() {
val customLogger = TestLogger()
ComposeStabilityAnalyzer.setLogger(customLogger)
ComposeStabilityAnalyzer.setEnabled(true)
@@ -114,7 +114,7 @@ class LoggerProviderTest {
}
@Test
- fun testLoggerProvider_changeLogger_midStream() {
+ fun testComposeStabilityAnalyzer_changeLogger_midStream() {
val logger1 = TestLogger()
val logger2 = TestLogger()
@@ -132,7 +132,7 @@ class LoggerProviderTest {
}
@Test
- fun testLoggerProvider_toggleEnabled() {
+ fun testComposeStabilityAnalyzer_toggleEnabled() {
val customLogger = TestLogger()
ComposeStabilityAnalyzer.setLogger(customLogger)