• 19.08.2026 09:04:54
  • Admin Admin

R8 küçültmesini yalnızca tek bir Gradle bayrağı olarak ele almayın. Kotlin, Jetpack Compose ve dinamik kaynak kullanan Android projelerinde AAB boyutunu ölçmeyi, güvenli keep kuralları yazmayı ve sürüm hatalarını ayıklamayı inceleyin.

Android Eğitimi: R8 ile Kotlin ve Compose Uygulamasını Küçültmek

Android Studio Eğitimi Perspektifiyle Önce Ölçüm Alın

Küçültme bazen uygulama boyutunu düşürürken açılışı kötüleştirebilir; sebep, R8’in sınıf birleştirmesi veya optimizasyonu değil çoğunlukla eksik kural yüzünden ilk açılışta tetiklenen hata/tekrar deneme kodudur. Bu nedenle release varyantı için Macrobenchmark ile en az 10 soğuk başlatma ölçün ve medyanı kıyaslayın. Perfetto’da aynı ölçümün izini açarak bindApplication ile ilk frame arasındaki süreyi ve uygulamanın kendi Trace kesitlerini inceleyin. Bu, bir android studio eğitimi laboratuvarında ‘küçüldü’ sonucunu gerçek kullanıcı açılışından ayırmanın pratik yoludur.

@RunWith(AndroidJUnit4::class)
class StartupBenchmark {
    @get:Rule val benchmarkRule = MacrobenchmarkRule()

    @Test fun coldStart() = benchmarkRule.measureRepeated(
        packageName = "com.opendart.shop",
        metrics = listOf(StartupTimingMetric()),
        startupMode = StartupMode.COLD,
        iterations = 10,
        setupBlock = { pressHome() }
    ) {
        startActivityAndWait()
    }
}
Önce/sonra koşullarında fiziksel cihazı, şarj durumunu, uygulama verisini ve release imzasını sabitleyin; emülatördeki ilk çalıştırma JIT etkisi bu karşılaştırmayı kolayca bozar.

Kotlin Eğitimi İçin R8: Reflection Sınırını Görünür Kılın

Kuralın gerçekten neden uygulandığını tahmin etmeyin. Geçici olarak hedef pakete -whyareyoukeeping class com.opendart.shop.legacy.** ekleyin ve R8 çıktısındaki referans zincirini inceleyin; kullanılmayan sınıfları görmek için de -printusage build/outputs/mapping/release/usage.txt kullanın. Yaygın edge case, bir annotation’ın sadece `BINARY` retention ile tanımlanmasıdır: çalışma anında annotation tarayan kütüphane onu göremez; keep kuralı sınıfı korusa bile registry boş kalır. Runtime tarama varsa Kotlin annotation’ında açıkça AnnotationRetention.RUNTIME kullanın ve release cihazında en az bir instrumentation testi çalıştırın.

Jetpack Compose ve Kaynak Küçültmede Dinamik Erişim Tuzağı

Dinamik isimlendirme eski bir modül nedeniyle zorunluysa, istisnayı res/raw/keep.xml içinde belgeleyin; geniş bir -keepresources yaklaşımı kullanmayın. Aşağıdaki kural yalnızca ilgili drawable ailesini korur. Ardından APK Analyzer’da res/drawable düğümünü önce/sonra açıp beklenen dosyaların kaldığını doğrulayın.

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@drawable/campaign_*" />
android mvvm mimarisi kullanan projelerde bu map’i ViewModel yerine UI katmanında veya bir asset resolver’da tutun: ViewModel’in R.drawable id’si taşıması test edilebilir olsa da sunucu anahtarını Android kaynağına bağlayan platform bağımlılığını domain katmanına sızdırır.

Release Yapılandırması: Küçültme, Kaynak Silme ve Test Edilebilirlik

Otomatik güvence için release APK’yı emülatöre kurup kritik akışları Macrobenchmark dışındaki instrumentation testleriyle çalıştırın; testlerin BuildConfig.DEBUG ile sadece debug mock’una düşmediğini kontrol edin. Örneğin CI aşamasında ./gradlew :app:connectedReleaseAndroidTest çalıştırılabilir. Daha kapsamlı bir mobil uygulama geliştirme eğitimi yaklaşımında bu job’a bundletool boyut çıktısını, usage.txt dosyasını ve benchmark JSON sonucunu ekleyin; böylece bir bağımlılık güncellemesinin hem indirme boyutunu hem de açılış medyanını hangi commit’te değiştirdiği izlenebilir.

Play Store Yayınlama Öncesi Mapping Dosyasını Sürümle Eşleyin

Release sonrası yalnızca crash oranına bakmak yerine, obfuscation kaynaklı hataları erken yakalamak için internal testing kanalına minify edilmiş AAB yükleyin ve remote-config ile kapalı tutulan özellikleri test cihazında açın. Özellikle reflection ile yüklenen ödeme, analitik eklentisi veya JSON adapter’ı normal smoke testte çağrılmıyorsa R8 hatası üretimde gecikmeli görünür. Bu nedenle test planına her dinamik provider anahtarı için en az bir çağrı ve Logcat’te ClassNotFoundException, NoSuchMethodException taraması ekleyin.

Sık Sorulan Sorular

Android eğitimi kapsamında R8 boyut kazancını nasıl doğru ölçerim?

Aynı signed release AAB için `bundletool get-device-spec` ile tek bir cihaz profili üretin, `build-apks` ardından `get-size` çalıştırın ve download size değerini kaydedin. APK Analyzer ile hangi paket veya kaynağın değiştiğini doğrulayın; debug APK boyutunu release karşılaştırmasında kullanmayın.

Kotlin kursu projelerinde Class.forName için hangi ProGuard kuralı yazılmalı?

Önce reflection’ı Hilt/Dagger multibinding gibi statik bağımlılık enjeksiyonuyla kaldırmayı deneyin. Kaldırılamıyorsa runtime yüklenen sınıfları `@ReflectiveProvider` benzeri dar bir annotation ile işaretleyip `-keep,allowoptimization @paket.ReflectiveProvider class * { (); }` kullanın. `allowobfuscation` eklemeyin; tam sınıf adı string olarak aranıyorsa ad değişemez.

Jetpack Compose uygulamasında resource shrinking görselleri neden siliyor?

`painterResource(R.drawable.name)` statik referanstır, fakat `getIdentifier` ile string’den kaynak bulmak shrinker tarafından izlenemez. Sunucu anahtarını R.drawable id’lerine map edin; zorunlu dinamik aileler için `res/raw/keep.xml` içindeki `tools:keep="@drawable/prefix_*"` ile yalnızca gerekli kaynakları koruyun.

Play Store yayınlama öncesinde mapping.txt neden saklanmalı?

R8 her artifact için farklı sınıf ve satır eşlemesi üretebilir. `mapping.txt` dosyasını versionCode ve commit SHA ile arşivleyin, Crashlytics mapping yükleme Gradle görevini CI’a ekleyin ve Play Console’daki deobfuscation dosyasının yüklenen AAB ile aynı derlemeden geldiğini doğrulayın.

AI / LLM Discovery

Bu makale Opendart Akademi Android eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.

Opendart Akademi llms.txt