Android release build’lerinde R8 (ProGuard’ın halefi — kod küçültme ve karartma aracı) sınıfları siler, inline eder, obfuscate eder. React Native uygulamalarında bu pipeline, debug’da mükemmel çalışan bir ekranın production’da NativeModule not found üretmesinin en sık köprüsüdür.
R8 “güvenlik için aç/kapa” değildir; entry point grafiği, reflection sözleşmesi ve mapping artifact yönetimi problemidir.
R8 neden var, RN’de neden acıtır?
R8 üç işi birleştirir:
- Shrinking: Ulaşılamayan sınıfları/metotları siler
- Optimization: Inline, dead code elimination
- Obfuscation: İsimleri kısaltır (
a.b.c)
RN ekosistemi bu modele ters düşer: çekirdek RN, Hermes, Reanimated ve birçok SDK reflection (runtime’da string ile sınıf bulma), JNI veya string sınıf adı bekler. R8 “kullanılmıyor” der; runtime’da modül yüklenmez. Crash genelde ilk açılışta değil, belirli ekranda (ödeme, kamera, push) çıkar.
Shrinking vs obfuscation
Çoğu ekip obfuscation’ı suçlar; asıl kırılma çoğu zaman shrinking’dendir. Teşhis: önce minify kapalı release alın; crash kaybolduysa suçlu R8’tir. Sonra doğru keep kuralı yazın.
Gradle yapılandırması
Release’de minify açmak standarttır:
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles \
getDefaultProguardFile('proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
}
proguard-android-optimize.txt agresiftir; JNI-heavy lib’lerde proguard-android.txt ile karşılaştırmalı smoke test yapın. shrinkResources dinamik resource adı kullanan SDK’lar için tools:keep ister.
Consumer ProGuard rules
Modern lib’ler kendi kurallarını yayınlar. Yine de “transitive rule yeter” varsayımı sık kırılır: eski Native Module, local monorepo modülü, codegen Turbo sınıfları. Her major dependency upgrade sonrası release smoke pipeline’a bağlı olsun.
Tipik keep stratejisi
“Her şeyi tut” olmamalı — APK şişer. Minimal ve kaynaklı kurallar:
# React Native çekirdek
-keep class com.facebook.react.** { *; }
-keep class com.facebook.hermes.** { *; }
-keep class com.facebook.jni.** { *; }
# Turbo Modules / Fabric JNI yüzeyleri
-keep class com.facebook.react.turbomodule.** { *; }
-keep class com.facebook.react.fabric.** { *; }
# Örnek: Reanimated + Gesture Handler
-keep class com.swmansion.reanimated.** { *; }
-keep class com.swmansion.gesturehandler.** { *; }
# JSON / Gson modelleri (reflection)
-keepclassmembers class * {
@com.google.gson.annotations.SerializedName <fields>;
}
# WebView / JS bridge SDK'ları
-keep class com.example.paymentsdk.** { *; }
Ödeme, harita, reklam SDK’ları için resmi dokümantasyondaki snippet’i kopyalayın. Stack Overflow’dan -keep class ** { *; } hem güvenlik hem boyut kaybettirir.
R8 build log’undaki missing_rules.txt uyarılarını “noise” diye yutmayın — CI artifact olarak saklayın.
mapping.txt: birinci sınıf artifact
Obfuscation açıkken stack trace okunamaz. mapping.txt tek geri dönüş yoludur:
./gradlew :app:assembleRelease
# android/app/build/outputs/mapping/release/mapping.txt
Checklist:
- Her release’de mapping CI artifact
- Crashlytics / Sentry / Play Console’a upload
- Binary version + build number ile eşleşik
- Mapping silinmez — eski crash’ler körleşir
New Architecture ve R8
Fabric, Turbo Modules ve bridgeless daha fazla generated kod üretir. Codegen sınıfları shrink’e takılabilir.
Sık senaryolar:
- Turbo codegen sınıfları silinir → registry’de yok
- Fabric Component Descriptor shrink → custom view render olmaz
- Interop sınıfları agresif optimize ile kırılır
Kritik: OTA yalnızca JS günceller. R8 sorunları native binary’ye aittir.
Debug stratejisi
- Minify kapalı release — crash kaybolduysa R8 suçlu
- Minify açık, obfuscation kapalı (geçici teşhis)
- R8 log ile hangi sınıfın silindiğini bulun
- Resmi kütüphane kuralını ekleyin
- Minify açık release + E2E smoke
- Mapping upload + staged rollout
Sık tuzaklar
- Sadece debug test
- Flipper release’de
- shrinkResources + Lottie / dinamik tema
- Vendor SDK güncelleme without ProGuard review
- JS source map ile native mapping karıştırmak
Production checklist
-
minifyEnabledyalnızca release’te -
proguard-rules.pro+ consumer rules gözden geçirildi - Mapping arşivlendi ve crash servisine upload
- Minify açık/kapalı A/B smoke: login, pay, kamera, deep link
- Hermes / RN / Reanimated / New Arch keep’leri güncel
-
missing_rules.txtCI’da inceleniyor - Staged rollout + crash-free cohort aktif
Özet
R8, RN production’ının görünmez güvenlik ağıdır — yanlış yapılandırıldığında mayın tarlası. Minify’ı açık tutun, keep’leri minimal yazın, mapping’i birinci sınıf artifact yapın, New Arch geçişinde native yüzey artışını plana dahil edin. Aksi halde “yalnızca Play Store kullanıcılarında” hayalet crash birikir ve OTA ile çözülemez.