ActivityResultLauncher: mi ez és hogyan kell használni

Szerző: IT Sectr Megjelenés: 2026-06-10 Olvasási idő: 9 perc

Az ActivityResultLauncher az Android Activity Result API komponense, amely az androidx.activity könyvtár Activity 1.2.0 verziójában került bevezetésre. Felváltja az elavult startActivityForResult és onActivityResult metódusokat, amelyek az Android SDK létrehozása óta annak részét képezték. A Android Developers (2024) szerint az új API kiküszöböli az Activity-hez való szoros kapcsolódás és a típusbiztonság hiányának problémáit. Az ActivityResultLauncher előre regisztrálásra kerül, és Contract-ot használ a bemeneti és kimeneti adatok szigorú típusosításához.

Főbb pontok

  • ActivityResultLauncher — az új API az Activity-től való eredmény lekérésére az elavult startActivityForResult helyett
  • Contract — az objektum, amely meghatározza a bemeneti és kimeneti adatok típusát egy adott forgatókönyvhöz
  • Regisztráció a registerForActivityResult segítségével történik a launch hívása előtt
  • Callback — a cél Activity befejezése után hívódik meg az eredménnyel
  • API elérhető Activity, Fragment és Compose számára az Activity 1.2.0-tól kezdve

Mi az ActivityResultLauncher

ActivityResultLauncher egy osztály az androidx.activity.result csomagból, amely típusbiztos mechanizmust biztosít az Activity elindításához és az eredmény fogadásához. A Launcher a registerForActivityResult metóduson keresztül jön létre, amely két paramétert fogad: Contract (leírja a bemeneti és kimeneti típusokat) és ActivityResultCallback (az eredmény feldolgozója). Regisztráció után a launcher készen áll a launch metóduson keresztüli meghívásra.

A legfontosabb különbség a régi API-hoz képest a regisztráció és az indítás szétválasztása. A regisztráció az inicializálási szakaszban történik (Activity.onCreate vagy Fragment.onCreate), a callback egyszer kapcsolódik a launcher-hez, és garantáltan aktiválódik az eredmény visszaérkezésekor. Ez kiküszöböli azt a problémát, amikor az onActivityResult váratlan sorrendben vagy egy megsemmisített Activity-n aktiválódott.

Az ActivityResultLauncher támogatja az összes olyan forgatókönyvet, amelyeket korábban az onActivityResult-on keresztül kezeltek: kamera indítása, galéria, kapcsolatok kérése, engedélyek és egyéni Activity-k. Emellett az API bővíthető: a fejlesztő saját Contract-okat hozhat létre az Activity-k közötti adatcsere specifikus forgatókönyveihez.

Miért váltotta fel az Activity Result API a startActivityForResult-ot

startActivityForResult az Android SDK API Level 1 (2008) verziója óta annak része volt, és több mint 12 évig az Activity-től való eredmény lekérésének fő módja maradt. Azonban ennek a metódusnak alapvető hiányosságai voltak, amelyeket a Google az Activity Result API-ban kiküszöbölt. Tekintsük át a fő problémákat, és hogy az új API hogyan oldja meg azokat.

1. probléma: szoros kapcsolódás az Activity-hez

A startActivityForResult metódus requestCode-on keresztül kapcsolódik az Activity-hez és Fragment-hez — egy tetszőleges egész szám, amely az onActivityResult-ba kerül továbbításra. A fejlesztő manuálisan párosította a kódot az elindított művelettel, ami hibákhoz vezetett a kód újrafelhasználásakor és öröklődéskor. Az ActivityResultLauncher teljesen megszünteti a requestCode-ot: a callback a regisztrációs szakaszban egy adott launcher-hez kapcsolódik, és csak azért hívódik meg.

2. probléma: az eredmény elvesztése képernyőforgatáskor

Konfigurációs változásoknál (képernyőforgatás, nyelvváltás) az Activity újra létrejött, és az onActivityResult nem aktiválódhatott — a callback elveszett. Az Activity Result API automatikusan elmenti és visszaállítja a launcher állapotát a SavedStateRegistry segítségével, ami garantálja az eredmény fogadását még az Activity újra létrehozása után is.

3. probléma: a típusbiztonság hiánya

A régi API az eredményt Intent-en keresztül Bundle-ben továbbította, ahol a kulcsokat és adattípusokat a fordító nem ellenőrizte. Az Activity Result API Contract-ot használ — egy generikus interfészt, amely meghatározza a bemeneti adatok típusát (I) és az eredmény típusát (O). A típus-eltérésekből adódó hibák a fordítási szakaszban észlelhetők, nem futásidőben.

JellemzőstartActivityForResultActivityResultLauncher
RequestCodeKézi kezelést igényelAutomatikus, nem szükséges
TípusbiztonságNincsGeneric Contract
Megőrzés forgatáskorElvészSavedStateRegistry
Minimális APIAPI Level 1Activity 1.2.0
Használat Compose-banNem támogatottrememberLauncherForActivityResult

Az Activity Result API fő szerződései

Contract egy ActivityResultContract<I, O> interfész, amely meghatározza, hogyan kell elindítani az Activity-t és hogyan kell értelmezni az eredményt. A Google beépített szerződések készletét kínálja a tipikus forgatókönyvekhez, amelyek a fejlesztői igények nagy részét lefedik.

StartIntentSenderForResult

StartIntentSenderForResult az alapszerződés az IntentSender elindításához. Rendszerszintű forgatókönyvekben használatos, például Google Sign-In-en keresztüli hitelesítéskor vagy Google Pay-en keresztüli fizetéskor. Bemeneti paraméter — PendingIntent, kimenet — ActivityResult kóddal és Intent-tel.

RequestMultiplePermissions

RequestMultiplePermissions a szerződés több engedély egyidejű kéréséhez Android 6.0+-ban. Bemeneti paraméter — String tömb az engedélyek neveivel, kimenet — Map<String, Boolean> az egyes kérések eredményével. Korábban ehhez kézi elemzésre volt szükség az onRequestPermissionsResult-ban a kérési kódok párosításával.

TakePicture és TakeVideo

TakePicture a szerződés fénykép készítéséhez a rendszerkamerán keresztül. Bemenet — Uri, ahová a fénykép mentésre kerül, kimenet — Boolean (siker). TakeVideo hasonlóan működik a videóval. Ezek a szerződések felváltják az elavult MediaStore.ACTION_IMAGE_CAPTURE-t, amely instabil viselkedést mutatott különböző eszközökön.

GetContent és OpenDocument

GetContent a szerződés tartalom kiválasztásához a rendszer választóján keresztül. Bemenet — MIME típus (pl. image/*), kimenet — a kiválasztott fájl Uri-ja. OpenDocument abban különbözik, hogy támogatja a többszörös kiválasztást és a dokumentumtípusok szerinti szűrést. Mindkét szerződés SAF-en (Storage Access Framework) keresztül működik.

CreateDocument és OpenDocumentTree

CreateDocument a szerződés új dokumentum létrehozásához a rendszer párbeszédablakán keresztül. A felhasználó kiválasztja a nevet és a mappát, a rendszer visszaadja az Uri-t az íráshoz. OpenDocumentTree hozzáférést biztosít egy teljes könyvtárhoz — a felhasználó kiválaszt egy mappát, és az alkalmazás tree-uri-t kap az összes fájl olvasásához és írásához.

Használat Activity-ben és Fragment-ben

Az ActivityResultLauncher használatának alapmintája a klasszikus Androidban két lépésből áll: regisztráció a registerForActivityResult segítségével az inicializálási szakaszban, és a launch meghívása a felhasználói műveletre válaszul. Tekintsünk egy tipikus példát a kép kiválasztására a galériából.

Regisztráció és indítás Activity-ben

Regisztrálja a launcher-t az Activity onCreate-jében — ez garantálja, hogy a callback készen álljon minden lehetséges hívás előtt. Soha ne regisztrálja a launcher-t közvetlenül az indítás előtt — ez megsérti az API szerződést, és az Activity újra létrehozásakor az eredmény elvesztéséhez vezethet.

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/*")
    }
}

Használat Fragment-ben

Fragment-ben a regisztráció az onCreate-ben, onAttach-ban vagy az onCreateView-ben történő inicializáláskor történik. A FragmentActivity a launcher-t a szülő Activity-n keresztül továbbítja, így az eredmény a Fragment-en belül kerül feldolgozásra, nem az Activity-ben. Ez javítja az enkapszulációt az onActivityResult-hoz képest, ahol az összes Fragment összes eredménye az Activity egyetlen metódusában gyűlt össze.

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

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

ActivityResultLauncher Jetpack Compose-ban

Jetpack Compose speciális composable funkcionalitást biztosít az Activity Result API-hoz — rememberLauncherForActivityResult. A klasszikus megközelítéssel ellentétben Compose-ban a launcher a remember segítségével a composable életciklusához kapcsolt objektumként jön létre. Ez lehetővé teszi az Activity Result API teljesen deklaratív stílusban történő használatát az Activity vagy Fragment közvetlen elérése nélkül.

rememberLauncherForActivityResult

rememberLauncherForActivityResult fogadja a Contract-ot és a callback-et, és visszaadja az ActivityResultLauncher-t. A launcher megőrződik a recompozíció során, és automatikusan törlődik a kompozícióból való kilépéskor. A launch hívása egy eseményre válaszul történik — például gombnyomásra vagy állapotváltozásra.

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

    Button(onClick = { launcher.launch("image/*") }) {
        Text("Fotó kiválasztása")
    }
}

Engedélyek kezelése Compose-ban

Engedélyek kérése Compose-ban szintén a rememberLauncherForActivityResult segítségével történik a RequestPermission vagy RequestMultiplePermissions szerződéssel. A Google az accompanist-permissions használatát javasolja, de a motorháztető alatt az is az Activity Result API-t használja. Az engedélyek állapotának ellenőrzéséhez kényelmes az állapotot remember-ben vagy ViewModel-ben tárolni.

Gyakori hibák és bevált gyakorlatok

Activity Result API kiküszöbölte a régi megközelítés számos problémáját, de helytelen használata új típusú hibákhoz vezethet. Tekintsük át a leggyakoribb problémákat és azok elkerülésének módjait.

Hiba: regisztráció lambda vagy korutin belsejében

A launcher regisztrációját a komponens inicializálásakor kell elvégezni — az Activity onCreate-jében vagy a Fragment inicializálójában. Ha a launcher-t lambda, callback vagy korutin belsejében regisztrálja, az Activity újra létrehozásakor a regisztráció megismétlődhet, és a régi launcher elveszíti a kapcsolatot az eredménnyel.

Hiba: több launcher regisztrálása ugyanazzal a kulccsal

Minden launcher egyedi kulcsot kap az állapot mentéséhez. Ha két launcher-t regisztrál ugyanazzal a Contract-tal egy komponensben, a SavedStateRegistry felülírhatja az egyik állapotát a másikkal. Az Android Studio figyelmeztet erre az UnnecessaryRegisterForActivityResult lint szabályon keresztül, de jobb az egyediséget manuálisan ellenőrizni.

Bevált gyakorlat: mindig kezelje a null eredményt

A felhasználó megszakíthatja a műveletet — megnyomhatja a rendszer vissza gombját, minimalizálhatja az alkalmazást, vagy átválthat egy másik alkalmazásra. Ebben az esetben a callback null értéket vagy ActivityResult-ot kap RESULT_CANCELED-del. Mindig ellenőrizze az eredményt null-ra a használat előtt a NullPointerException elkerülése érdekében.

Bevált gyakorlat: egyéni Contract-ok újrafelhasználható logikához

Ha az alkalmazása gyakran indít hasonló forgatókönyveket — például név és telefonszám visszaadásával történő kapcsolatválasztást — hozzon létre saját Contract-ot. Ez javítja a kód olvashatóságát, és lehetővé teszi az indítási és eredményfeldolgozási logika központosított módosítását.

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) }
}

Gyakran Ismételt Kérdések

Használható az ActivityResultLauncher ViewModel-ben?

Nem — az ActivityResultLauncher Activity vagy Fragment kontextust igényel a regisztrációhoz. A ViewModel-t csak állapot tárolására használja, a launcher-t pedig Activity-ben vagy Fragment-ben hozza létre, és az eredményt adja át a ViewModel-nek.

Milyen minimális SDK szükséges az Activity Result API-hoz?

Activity Result API az activity-ktx 1.2.0 könyvtártól kezdve érhető el. Minimális SDK — API Level 14 (Android 4.0), de a legtöbb szerződés csak API Level 19+-on működik.

Mi történik, ha a launch kétszer hívódik meg az eredmény megérkezése előtt?

A launch ismételt meghívása az első művelet befejezése előtt figyelmen kívül lesz hagyva. Az Activity Result API nem támogat párhuzamos indításokat — várja meg az első művelet callback-jét az új hívás előtt.

Mivel helyettesítsük az onActivityResult-ot a régi kódban?

A migráció a startActivityForResult hívásának registerForActivityResult-ra cserélésével történik a megfelelő Contract-tal. Távolítsa el az onActivityResult-ot, és kezelje az eredményt a launcher callback-jében. A Google migrációs útmutatót biztosít az Android Developers dokumentációjában.

Működik az ActivityResultLauncher olyan könyvtárakkal, mint az ML Kit vagy a Barcode Scanner?

Igen, sok könyvtár támogatja az integrációt az ActivityResultContracts-en keresztül. Például az ML Kit Barcode Scanner a StartIntentSenderForResult-ot használja a szkanner indításához. Ellenőrizze az adott könyvtár dokumentációját.

Összefoglalás

  • ActivityResultLauncher — modern típusbiztos API az elavult startActivityForResult helyett
  • Contract meghatározza a bemeneti és kimeneti adatok típusát, megszüntetve a requestCode kézi párosítását
  • Regisztráció az inicializálási szakaszban történik, az eredmény garantáltan átadásra kerül a callback-en keresztül
  • Beépített szerződések lefedik a kamerát, galériát, engedélyeket, dokumentumokat és kapcsolatokat
  • Jetpack Compose a rememberLauncherForActivityResult-ot használja az API-val való munkához
  • Egyéni Contract lehetővé teszi az indítási logika újrafelhasználását a komponensek között
  • API megőrzi az állapotot konfigurációs változások esetén a SavedStateRegistry segítségével

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is