ActivityResultLauncher: nedir ve nasıl kullanılır

Yazar: IT Sectr Yayınlanma: 2026-06-10 Okuma süresi: 9 dk

ActivityResultLauncher, androidx.activity kütüphanesinin Activity 1.2.0 sürümünde tanıtılan Android Activity Result API’nin bir bileşenidir. Android SDK’nın oluşturulmasından bu yana parçası olan kullanımdan kaldırılmış startActivityForResult ve onActivityResult yöntemlerinin yerini alır. Android Developers (2024)’e göre, yeni API, Activity ile sıkı bağlantı ve tür güvenliği eksikliği sorunlarını ortadan kaldırır. ActivityResultLauncher önceden kaydedilir ve giriş ve çıkış verilerinin sıkı tür tanımlaması için Contract kullanır.

Ana Noktalar

  • ActivityResultLauncher — kullanımdan kaldırılan startActivityForResult yerine Activity’den sonuç almak için yeni API
  • Contract — belirli bir senaryo için giriş ve çıkış verilerinin türünü tanımlayan bir nesne
  • Kayıt launch çağırmadan önce registerForActivityResult aracılığıyla yapılır
  • Callback hedef Activity bir sonuçla bittiğinde çağrılır
  • API kullanılabilir Activity 1.2.0’dan itibaren Activity, Fragment ve Compose için

ActivityResultLauncher nedir

ActivityResultLauncher, androidx.activity.result paketinden bir sınıftır ve bir Activity başlatmak ve sonuç almak için tür güvenli bir mekanizma sağlar. Launcher, iki parametre alan registerForActivityResult yöntemiyle oluşturulur: Contract (giriş ve çıkış türlerini tanımlar) ve ActivityResultCallback (sonuç işleyicisi). Kayıttan sonra launcher, launch yöntemiyle çağrılmaya hazırdır.

Eski API’den temel fark, kayıt ve başlatmanın ayrılmasıdır. Kayıt, başlatma aşamasında (Activity.onCreate veya Fragment.onCreate) gerçekleştirilir, callback launcher’a bir kez bağlanır ve sonuç döndüğünde çalışması garanti edilir. Bu, onActivityResult’un beklenmedik bir sırada veya yok edilmiş bir Activity’de çalışması sorununu ortadan kaldırır.

ActivityResultLauncher, daha önce onActivityResult aracılığıyla işlenen tüm senaryoları destekler: kamerayı başlatma, galeri, kişileri isteme, izinler ve özel Activity’ler. Ayrıca, API genişletilebilir: geliştiriciler, Activity’ler arasındaki belirli veri alışveriş senaryoları için özel Contract’lar oluşturabilir.

Activity Result API neden startActivityForResult’un yerini aldı

startActivityForResult, API Level 1’den (2008) beri Android SDK’nın bir parçasıydı ve 12 yıldan fazla bir süre boyunca bir Activity’den sonuç almanın ana yöntemi olarak kaldı. Ancak, bu yöntemin Google’ın Activity Result API’de çözdüğü temel eksiklikleri vardı. Ana sorunlara ve yeni API’nin bunları nasıl çözdüğüne bakalım.

Sorun 1: Activity ile sıkı bağlantı

startActivityForResult yöntemi, requestCode (onActivityResult’a iletilen rastgele bir tam sayı) aracılığıyla Activity ve Fragment’e bağlıdır. Geliştirici, kodu başlatılan işlemle manuel olarak eşleştiriyordu ve bu da kod yeniden kullanımı ve kalıtımda hatalara yol açıyordu. ActivityResultLauncher requestCode’u tamamen ortadan kaldırır: callback, kayıt sırasında belirli bir launcher’a bağlanır ve yalnızca onun için çağrılır.

Sorun 2: Ekran döndürmede sonuç kaybı

Yapılandırma değişiklikleri sırasında (ekran döndürme, dil değişimi), Activity yeniden oluşturuluyordu ve onActivityResult çalışmayabilirdi — callback kayboluyordu. Activity Result API, SavedStateRegistry aracılığıyla launcher durumunu otomatik olarak kaydeder ve geri yükler, böylece Activity yeniden oluşturulduktan sonra bile sonucun alınmasını garanti eder.

Sorun 3: Tür güvenliği eksikliği

Eski API, anahtarların ve veri türlerinin derleyici tarafından kontrol edilmediği bir Bundle ile Intent aracılığıyla sonucu iletiyordu. Activity Result API, Contract — giriş veri türünü (I) ve sonuç türünü (O) tanımlayan genel bir arayüz — kullanır. Tür uyuşmazlığı hataları, çalışma zamanında değil, derleme zamanında yakalanır.

ÖzellikstartActivityForResultActivityResultLauncher
RequestCodeManuel yönetim gerekliOtomatik, gerekli değil
Tür güvenliğiHayırGenel Contract
Döndürmede kaydetmeKaybolurSavedStateRegistry
Minimum APIAPI Level 1Activity 1.2.0
Compose’da kullanımDesteklenmezrememberLauncherForActivityResult

Activity Result API’nin ana kontratları

Contract, bir Activity’nin nasıl başlatılacağını ve sonucun nasıl yorumlanacağını tanımlayan ActivityResultContract<I, O> arayüzüdür. Google, çoğu geliştirici ihtiyacını karşılayan tipik senaryolar için bir dizi yerleşik kontrat sağlar.

StartIntentSenderForResult

StartIntentSenderForResult — IntentSender başlatmak için temel bir kontrat. Sistem senaryolarında kullanılır, örneğin Google Sign-In ile yetkilendirme veya Google Pay ile ödeme yaparken. Giriş parametresi PendingIntent’tir, çıkış ise kod ve Intent ile ActivityResult’tur.

RequestMultiplePermissions

RequestMultiplePermissions — Android 6.0+’da aynı anda birden fazla izin istemek için bir kontrat. Giriş parametresi izin adlarından oluşan bir String dizisidir, çıkış ise her isteğin sonucunu içeren Map<String, Boolean>’dur. Daha önce bu, onRequestPermissionsResult içinde istek kodlarını eşleştirerek manuel ayrıştırma gerektiriyordu.

TakePicture ve TakeVideo

TakePicture — sistem kamerasıyla fotoğraf çekmek için bir kontrat. Giriş, görüntünün kaydedileceği Uri’dir, çıkış ise Boolean (başarı)’dır. TakeVideo video ile benzer şekilde çalışır. Bu kontratlar, farklı cihazlarda dengesiz davranış gösteren kullanımdan kaldırılmış MediaStore.ACTION_IMAGE_CAPTURE’un yerini alır.

GetContent ve OpenDocument

GetContent — sistem seçici aracılığıyla içerik seçmek için bir kontrat. Giriş bir MIME türüdür (örn. image/*), çıkış seçilen dosyanın Uri’sidir. OpenDocument, çoklu seçim ve belge türlerine göre filtrelemeyi desteklemesiyle ayrılır. Her iki kontrat da SAF (Storage Access Framework) aracılığıyla çalışır.

CreateDocument ve OpenDocumentTree

CreateDocument — sistem diyaloğu aracılığıyla yeni bir belge oluşturmak için bir kontrat. Kullanıcı bir ad ve klasör seçer, sistem yazma için bir Uri döndürür. OpenDocumentTree tam bir dizine erişim sağlar — kullanıcı bir klasör seçer ve uygulama içindeki tüm dosyaları okumak ve yazmak için bir tree-uri alır.

Activity ve Fragment’te kullanım

Klasik Android’de ActivityResultLauncher kullanmanın temel deseni iki adımdan oluşur: başlatma sırasında registerForActivityResult aracılığıyla kayıt ve kullanıcı eylemine yanıt olarak launch çağrısı. Galeriden bir görüntü seçmenin tipik bir örneğine bakalım.

Activity’de kayıt ve başlatma

Launcher’ı Activity’nin onCreate’inde kaydedin — bu, olası herhangi bir çağrıdan önce callback’in hazır olmasını sağlar. Bir launcher’ı asla başlatmadan hemen önce kaydetmeyin — bu API kontratını ihlal eder ve Activity yeniden oluşturulduğunda sonuç kaybına yol açabilir.

kotlin
class MainActivity : AppCompatActivity() {
    private val pickImageLauncher =
        registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
            uri?.let { binding.imageView.setImageURI(it) }
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        pickImageLauncher.launch("image/*")
    }
}

Fragment’te kullanım

Bir Fragment’te kayıt, onCreate, onAttach veya onCreateView’de başlatma sırasında yapılır. FragmentActivity, launcher’ı üst Activity aracılığıyla iletir, böylece sonuç Activity’de değil, Fragment içinde işlenir. Bu, tüm Fragment’lerden gelen tüm sonuçların tek bir Activity yönteminde toplandığı onActivityResult’a kıyasla kapsüllemeyi iyileştirir.

kotlin
class ProfileFragment : Fragment() {
    private val cameraLauncher =
        registerForActivityResult(ActivityResultContracts.TakePicture()) { success ->
            if (success) { updateProfilePhoto() }
        }

    fun takePhoto(photoUri: Uri) {
        cameraLauncher.launch(photoUri)
    }
}

Jetpack Compose’da ActivityResultLauncher

Jetpack Compose, Activity Result API için özel bir composable işlevi sağlar — rememberLauncherForActivityResult. Klasik yaklaşımın aksine, Compose’da launcher, remember aracılığıyla composable yaşam döngüsüne bağlı bir nesne olarak oluşturulur. Bu, Activity veya Fragment’e doğrudan erişim olmadan Activity Result API’nin tamamen bildirimsel bir stilde kullanılmasına olanak tanır.

rememberLauncherForActivityResult

rememberLauncherForActivityResult bir Contract ve callback alır ve bir ActivityResultLauncher döndürür. Launcher, yeniden oluşturma sırasında korunur ve kompozisyondan çıkıldığında otomatik olarak temizlenir. launch çağrısı bir olaya yanıt olarak gerçekleşir — örneğin, bir düğme tıklaması veya durum değişikliği.

kotlin
@Composable
fun PhotoPicker() {
    val context = LocalContext.current
    val launcher = rememberLauncherForActivityResult(
        ActivityResultContracts.GetContent()
    ) { uri -> handleImage(uri) }

    Button(onClick = { launcher.launch("image/*") }) {
        Text("Fotoğraf seç")
    }
}

Compose’da izin yönetimi

Compose’da izin talepleri de RequestPermission veya RequestMultiplePermissions kontratı ile rememberLauncherForActivityResult aracılığıyla yapılır. Google, accompanist-permissions kullanımını önerir, ancak içte o da Activity Result API’yi kullanır. İzin durumunu izlemek için durumu remember veya ViewModel’de saklamak uygundur.

Yaygın hatalar ve en iyi uygulamalar

Activity Result API, eski yaklaşımın birçok sorununu ortadan kaldırdı, ancak yanlış kullanım yeni tür hatalara yol açabilir. En yaygın sorunlara ve bunlardan nasıl kaçınılacağına bakalım.

Hata: lambda veya coroutine içinde kayıt

Launcher’ın kaydı, bileşen başlatma sırasında — Activity’nin onCreate’inde veya Fragment başlatıcısında yapılmalıdır. Launcher’ı bir lambda, callback veya coroutine içinde kaydederseniz, Activity yeniden oluşturulduğunda kayıt tekrar yapılabilir ve eski launcher sonuçla bağlantısını kaybeder.

Hata: aynı anahtarla birden çok launcher kaydetme

Her launcher durum kaydetme için benzersiz bir anahtar alır. Bir bileşende aynı Contract’a sahip iki launcher kaydederseniz, SavedStateRegistry birinin durumunu diğeriyle üzerine yazabilir. Android Studio, lint kuralı UnnecessaryRegisterForActivityResult aracılığıyla bu konuda uyarır, ancak benzersizliği manuel olarak kontrol etmek daha iyidir.

En iyi uygulama: her zaman null sonucu işleme

Kullanıcı eylemi iptal edebilir — sistem geri düğmesine basabilir, uygulamayı küçültebilir veya başka bir uygulamaya geçebilir. Bu durumda, callback null veya RESULT_CANCELED ile ActivityResult alır. NullPointerException’ı önlemek için kullanmadan önce sonucu her zaman null açısından kontrol edin.

En iyi uygulama: yeniden kullanılabilir mantık için özel Contract’lar

Uygulamanız sık sık benzer senaryolar başlatıyorsa — örneğin, bir kişi seçip ad ve telefon döndürmek — özel bir Contract oluşturun. Bu, kod okunabilirliğini artırır ve başlatma ve sonuç işleme mantığında merkezi değişikliklere olanak tanır.

kotlin
class PickContactContract : ActivityResultContract<Void, ContactData?>() {
    override fun createIntent(context: Context, input: Void?) =
        Intent(Intent.ACTION_PICK).setType(ContactsContract.Contacts.CONTENT_TYPE)

    override fun parseResult(resultCode: Int, intent: Intent?) =
        intent?.data?.let { queryContact(it) }
}

Sıkça Sorulan Sorular

ActivityResultLauncher ViewModel’de kullanılabilir mi?

Hayır — ActivityResultLauncher kayıt için bir Activity veya Fragment bağlamı gerektirir. ViewModel’i yalnızca durum depolamak için kullanın ve launcher’ı Activity veya Fragment’te oluşturup sonucu ViewModel’e iletin.

Activity Result API için hangi minimum SDK gereklidir?

Activity Result API, activity-ktx 1.2.0 kütüphanesinden itibaren kullanılabilir. Minimum SDK API Level 14’tür (Android 4.0), ancak çoğu kontrat yalnızca API Level 19+’da çalışır.

Sonuç alınmadan önce launch iki kez çağrılırsa ne olur?

İlk işlem tamamlanmadan önce launch’ın tekrarlanan çağrısı yok sayılır. Activity Result API paralel başlatmaları desteklemez — yeni bir çağrı yapmadan önce ilk işlemden callback bekleyin.

Eski kodda onActivityResult nasıl değiştirilir?

Geçiş, startActivityForResult çağrısını uygun Contract ile registerForActivityResult ile değiştirerek yapılır. onActivityResult’u kaldırın ve sonucu launcher callback’inde işleyin. Google, Android Developers belgelerinde bir geçiş kılavuzu sağlar.

ActivityResultLauncher, ML Kit veya Barcode Scanner gibi kütüphanelerle çalışır mı?

Evet, birçok kütüphane ActivityResultContracts aracılığıyla entegrasyonu destekler. Örneğin, ML Kit Barcode Scanner, tarayıcıyı başlatmak için StartIntentSenderForResult kullanır. Belirli kütüphanenin belgelerini kontrol edin.

Özet

  • ActivityResultLauncher — kullanımdan kaldırılan startActivityForResult’un yerini alan modern tür güvenli API
  • Contract giriş ve çıkış veri türlerini tanımlar, manuel requestCode eşleştirmesini ortadan kaldırır
  • Kayıt başlatma sırasında yapılır, sonuç callback aracılığıyla garanti edilir
  • Yerleşik kontratlar kamera, galeri, izinler, belgeler ve kişileri kapsar
  • Jetpack Compose API ile çalışmak için rememberLauncherForActivityResult kullanır
  • Özel Contract’lar bileşenler arasında başlatma mantığını yeniden kullanmaya olanak tanır
  • API, SavedStateRegistry aracılığıyla yapılandırma değişiklikleri sırasında durumu korur

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun