ActivityResultLauncher: bu nədir və necə istifadə etməli

Müəllif: IT Sectr Dərc olunub: 2026-06-10 Oxuma vaxtı: 9 dəq

ActivityResultLauncher — Android Activity Result API-nin komponentidir, androidx.activity kitabxanasının Activity 1.2.0 versiyasında təqdim edilmişdir. Android SDK-nın yarandığı andan etibarən onun hissəsi olan köhnəlmiş startActivityForResult və onActivityResult metodlarını əvəz edir. Android Developers (2024)-ə görə, yeni API Activity ilə sərt əlaqə və tip təhlükəsizliyinin olmaması problemlərini aradan qaldırır. ActivityResultLauncher əvvəlcədən qeydiyyatdan keçir və giriş və çıxış məlumatlarının ciddi tipləşdirilməsi üçün Contract istifadə edir.

Əsas məqamlar

  • ActivityResultLauncher — köhnəlmiş startActivityForResult əvəzinə Activity-dən nəticə almaq üçün yeni API
  • Contract — konkret ssenari üçün giriş və çıxış məlumatlarının tipini təyin edən obyekt
  • Qeydiyyat launch çağırışından əvvəl registerForActivityResult vasitəsilə həyata keçirilir
  • Callback — hədəf Activity nəticə ilə başa çatdıqdan sonra çağırılır
  • API mövcuddur Activity 1.2.0-dan başlayaraq Activity, Fragment və Compose üçün

ActivityResultLauncher nədir

ActivityResultLauncher — androidx.activity.result paketindən olan sinifdir, Activity-ni işə salmaq və nəticə almaq üçün tip təhlükəsiz mexanizm təqdim edir. Launcher iki parametr qəbul edən registerForActivityResult metodu vasitəsilə yaradılır: Contract (giriş və çıxış tiplərini təsvir edir) və ActivityResultCallback (nəticə emalçısı). Qeydiyyatdan sonra launcher launch metodu vasitəsilə çağırışa hazırdır.

Köhnə API-dən əsas fərq — qeydiyyat və işə salmanın ayrılmasıdır. Qeydiyyat inisiallaşdırma mərhələsində (Activity.onCreate və ya Fragment.onCreate) həyata keçirilir, callback launcher ilə bir dəfə əlaqələndirilir və nəticə qayıtdıqda zəmanətli işə düşür. Bu, onActivityResult-un gözlənilməz ardıcıllıqda və ya məhv edilmiş Activity-də işə düşməsi problemini aradan qaldırır.

ActivityResultLauncher bütün ssenariləri dəstəkləyir ki, bunlar da əvvəllər onActivityResult vasitəsilə emal olunurdu: kamera işə salma, qalereya, kontakt sorğusu, icazələr və fərdi Activity-lər. Bundan əlavə, API genişləndirilə biləndir: tərtibatçı Activity-lər arasında məlumat mübadiləsinin spesifik ssenariləri üçün öz Contract-larını yarada bilər.

Niyə Activity Result API startActivityForResult-u əvəz etdi

startActivityForResult Android SDK-nın API Level 1 (2008) versiyasından etibarən onun hissəsi idi və 12 ildən çox müddət ərzində Activity-dən nəticə almağın əsas yolu olaraq qaldı. Lakin bu metodun Activity Result API-də Google-un aradan qaldırdığı fundamental çatışmazlıqları var idi. Əsas problemlərə və yeni API-nin onları necə həll etdiyinə baxaq.

Problem 1: Activity ilə sərt əlaqə

startActivityForResult metodu Activity və Fragment ilə requestCode vasitəsilə əlaqələndirilir — onActivityResult-a ötürülən ixtiyari tam ədəd. Tərtibatçı kodu işə salınmış əməliyyatla əl ilə uyğunlaşdırırdı, bu da kodun təkrar istifadəsi və vərəsəlik zamanı səhvlərə səbəb olurdu. ActivityResultLauncher requestCode-u tamamilə aradan qaldırır: callback qeydiyyat mərhələsində konkret launcher ilə əlaqələndirilir və yalnız onun üçün çağırılır.

Problem 2: ekranın döndərilməsi zamanı nəticənin itirilməsi

Konfiqurasiya dəyişiklikləri zamanı (ekranın döndərilməsi, dilin dəyişməsi) Activity yenidən yaradılırdı və onActivityResult işə düşməyə bilərdi — callback itirdi. Activity Result API SavedStateRegistry vasitəsilə launcher vəziyyətini avtomatik saxlayır və bərpa edir, bu da Activity-nin yenidən yaradılmasından sonra belə nəticənin alınmasını təmin edir.

Problem 3: tip təhlükəsizliyinin olmaması

Köhnə API nəticəni Bundle ilə Intent vasitəsilə ötürürdü, burada açarlar və məlumat tipləri kompilyator tərəfindən yoxlanılmırdı. Activity Result API Contract — giriş məlumatlarının tipini (I) və nəticə tipini (O) təyin edən generic interfeys istifadə edir. Tip uyğunsuzluğu səhvləri runtime-da deyil, kompilyasiya mərhələsində aşkar edilir.

XüsusiyyətstartActivityForResultActivityResultLauncher
RequestCodeƏl ilə idarə tələb olunurAvtomatik, tələb olunmur
Tip təhlükəsizliyiYoxGeneric Contract
Döndərmədə saxlanmaİtirilirSavedStateRegistry
Minimal APIAPI Level 1Activity 1.2.0
Compose-da istifadəDəstəklənmirrememberLauncherForActivityResult

Activity Result API-nin əsas kontraktları

Contract — ActivityResultContract<I, O> interfeysidir, Activity-ni necə işə salmağı və nəticəni necə interpretasiya etməyi təyin edir. Google tərtibatçının əksər ehtiyaclarını əhatə edən tipik ssenarilər üçün daxili kontraktlar dəsti təqdim edir.

StartIntentSenderForResult

StartIntentSenderForResult — IntentSender-i işə salmaq üçün əsas kontrakt. Sistem ssenarilərində, məsələn Google Sign-In vasitəsilə autorizasiya və ya Google Pay ilə ödəniş zamanı istifadə olunur. Giriş parametri — PendingIntent, çıxış — kod və Intent ilə ActivityResult.

RequestMultiplePermissions

RequestMultiplePermissions — Android 6.0+-da eyni anda bir neçə icazə tələb etmək üçün kontrakt. Giriş parametri — icazə adları ilə String massivi, çıxış — hər sorğunun nəticəsi ilə Map<String, Boolean>. Əvvəllər bu, sorğu kodlarının uyğunlaşdırılması ilə onRequestPermissionsResult-da əl ilə təhlil tələb edirdi.

TakePicture və TakeVideo

TakePicture — sistem kamerası vasitəsilə şəkil çəkmək üçün kontrakt. Giriş — şəklin saxlanacağı Uri, çıxış — Boolean (uğur). TakeVideo eyni şəkildə video ilə işləyir. Bu kontraktlar müxtəlif cihazlarda qeyri-sabit davranışı olan köhnəlmiş MediaStore.ACTION_IMAGE_CAPTURE-ni əvəz edir.

GetContent və OpenDocument

GetContent — sistem picker vasitəsilə məzmun seçmək üçün kontrakt. Giriş — MIME tipi (məsələn image/*), çıxış — seçilmiş faylın Uri-si. OpenDocument çoxsaylı seçim dəstəyi və sənəd tipləri üzrə filtrləmə ilə fərqlənir. Hər iki kontrakt SAF (Storage Access Framework) vasitəsilə işləyir.

CreateDocument və OpenDocumentTree

CreateDocument — sistem dialoq pəncərəsi vasitəsilə yeni sənəd yaratmaq üçün kontrakt. İstifadəçi ad və qovluq seçir, sistem yazmaq üçün Uri qaytarır. OpenDocumentTree bütün kataloqa giriş verir — istifadəçi qovluq seçir və tətbiq daxilindəki bütün faylları oxumaq və yazmaq üçün tree-uri alır.

Activity və Fragment-də istifadə

Klassik Android-də ActivityResultLauncher istifadəsinin əsas nümunəsi iki addımdan ibarətdir: inisiallaşdırma mərhələsində registerForActivityResult vasitəsilə qeydiyyat və istifadəçinin hərəkətinə cavab olaraq launch çağırışı. Qalereyadan şəkil seçiminin tipik nümunəsinə baxaq.

Activity-də qeydiyyat və işə salma

Launcher-i Activity-nin onCreate-də qeydiyyatdan keçirin — bu, callback-in hər hansı mümkün çağırışdan əvvəl hazır olmasını təmin edir. Heç vaxt launcher-i birbaşa işə salmadan əvvəl qeydiyyatdan keçirməyin — bu, API kontraktını pozur və Activity-nin yenidən yaradılması zamanı nəticənin itirilməsinə səbəb ola bilər.

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-də istifadə

Fragment-də qeydiyyat onCreate, onAttach və ya onCreateView-də inisiallaşdırmada həyata keçirilir. FragmentActivity launcher-i valideyn Activity vasitəsilə ötürür, buna görə də nəticə Activity-də deyil, Fragment daxilində emal olunur. Bu, onActivityResult ilə müqayisədə enkapsulyasiyanı yaxşılaşdırır, burada bütün Fragment-lərdən bütün nəticələr Activity-nin bir metodunda toplanırdı.

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 üçün xüsusi composable funksionallığı təqdim edir — rememberLauncherForActivityResult. Klassik yanaşmadan fərqli olaraq, Compose-da launcher remember vasitəsilə composable həyat dövrünə bağlanmış obyekt kimi yaradılır. Bu, Activity və ya Fragment-ə birbaşa giriş olmadan Activity Result API-dən tam deklarativ üslubda istifadə etməyə imkan verir.

rememberLauncherForActivityResult

rememberLauncherForActivityResult Contract və callback qəbul edir, ActivityResultLauncher qaytarır. Launcher rekompozisiya zamanı saxlanılır və kompozisiyadan çıxışda avtomatik təmizlənir. launch çağırışı hadisəyə cavab olaraq baş verir — məsələn, düymənin kliklənməsi və ya vəziyyətin dəyişməsi.

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

    Button(onClick = { launcher.launch("image/*") }) {
        Text("Şəkil seç")
    }
}

Compose-da icazələrin emalı

Compose-da icazələrin tələbi də RequestPermission və ya RequestMultiplePermissions kontraktı ilə rememberLauncherForActivityResult vasitəsilə həyata keçirilir. Google accompanist-permissions istifadə etməyi tövsiyə edir, lakin o da daxili olaraq Activity Result API-dən istifadə edir. İcazə vəziyyətinə nəzarət üçün statusu remember və ya ViewModel-də saxlamaq rahatdır.

Tipik səhvlər və ən yaxşı təcrübələr

Activity Result API köhnə yanaşmanın bir çox problemlərini aradan qaldırdı, lakin onun düzgün istifadə edilməməsi yeni növ səhvlərə səbəb ola bilər. Ən çox yayılmış problemlərə və onlardan qaçma yollarına baxaq.

Səhv: lambda və ya korutin daxilində qeydiyyat

Launcher-in qeydiyyatı komponentin inisiallaşdırılması zamanı — Activity-nin onCreate-də və ya Fragment-in inisiallaşdırıcısında aparılmalıdır. Əgər launcher-i lambda, callback və ya korutin daxilində qeydiyyatdan keçirsəniz, Activity yenidən yaradıldıqda qeydiyyat təkrar edilə bilər və köhnə launcher nəticə ilə əlaqəsini itirər.

Səhv: eyni açarla bir neçə launcher-in qeydiyyatı

Hər launcher vəziyyəti saxlamaq üçün unikal açar alır. Bir komponentdə eyni Contract ilə iki launcher qeydiyyatdan keçirsəniz, SavedStateRegistry birinin vəziyyətini digərinin üzərinə yaza bilər. Android Studio bu barədə UnnecessaryRegisterForActivityResult lint qaydası ilə xəbərdarlıq edir, lakin unikallığı əl ilə idarə etmək daha yaxşıdır.

Ən yaxşı təcrübə: həmişə null nəticəni emal etmək

İstifadəçi əməliyyatı ləğv edə bilər — sistemin geri düyməsini basa, tətbiqi kiçildə və ya başqa tətbiqə keçə bilər. Bu halda callback null və ya RESULT_CANCELED ilə ActivityResult alacaq. NullPointerException-dan qaçmaq üçün istifadədən əvvəl nəticəni həmişə null olub-olmadığını yoxlayın.

Ən yaxşı təcrübə: təkrar istifadə olunan məntiq üçün fərdi Contract

Əgər tətbiqiniz tez-tez eyni tipli ssenariləri işə salırsa — məsələn, ad və telefon qaytaran kontakt seçimi — öz Contract-ınızı yaradın. Bu, kodun oxunaqlılığını yaxşılaşdırır və işə salma və nəticənin emalı məntiqini mərkəzləşdirilmiş şəkildə dəyişməyə imkan verir.

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

Tez-tez verilən suallar

ActivityResultLauncher-dən ViewModel-də istifadə etmək olarmı?

Xeyr — ActivityResultLauncher qeydiyyat üçün Activity və ya Fragment konteksti tələb edir. ViewModel-dən yalnız vəziyyəti saxlamaq üçün istifadə edin, launcher-i isə Activity və ya Fragment-də yaradın və nəticəni ViewModel-ə ötürün.

Activity Result API üçün hansı minimal SDK tələb olunur?

Activity Result API activity-ktx 1.2.0 kitabxanasından etibarən mövcuddur. Minimal SDK — API Level 14 (Android 4.0), lakin əksər kontraktlar yalnız API Level 19+-da işləyir.

Nəticə alınmazdan əvvəl launch iki dəfə çağırılsa nə olar?

Təkrar launch çağırışı birinci əməliyyat tamamlanana qədər nəzərə alınmayacaq. Activity Result API paralel işə salmaları dəstəkləmir — yeni çağırışdan əvvəl birinci əməliyyatdan callback gözləyin.

Köhnə kodda onActivityResult-u nə ilə əvəz etməli?

Miqrasiya startActivityForResult çağırışının müvafiq Contract ilə registerForActivityResult ilə əvəz edilməsi ilə həyata keçirilir. onActivityResult-u silin və nəticəni launcher callback-də emal edin. Google Android Developers sənədlərində miqrasiya təlimatı təqdim edir.

ActivityResultLauncher ML Kit və ya Barcode Scanner kimi kitabxanalarla işləyirmi?

Bəli, bir çox kitabxana ActivityResultContracts vasitəsilə inteqrasiyanı dəstəkləyir. Məsələn, ML Kit Barcode Scanner skaneri işə salmaq üçün StartIntentSenderForResult istifadə edir. Xüsusi kitabxananın sənədlərini yoxlayın.

Nəticə

  • ActivityResultLauncher — köhnəlmiş startActivityForResult əvəzinə müasir tip təhlükəsiz API
  • Contract giriş və çıxış məlumatlarının tipini təyin edir, requestCode-un əl ilə uyğunlaşdırılmasını aradan qaldırır
  • Qeydiyyat inisiallaşdırma mərhələsində həyata keçirilir, nəticə callback vasitəsilə zəmanətli çatdırılır
  • Daxili kontraktlar kamera, qalereya, icazələr, sənədlər və kontaktları əhatə edir
  • Jetpack Compose API ilə iş üçün rememberLauncherForActivityResult istifadə edir
  • Fərdi Contract komponentlər arasında işəsalma məntiqinin təkrar istifadəsinə imkan verir
  • API vəziyyəti saxlayır konfiqurasiya dəyişiklikləri zamanı SavedStateRegistry vasitəsilə

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun