ActivityResultLauncher: یہ کیا ہے اور اسے کیسے استعمال کریں

مصنف: IT Sectr اشاعت: 2026-06-10 مطالعے کا وقت: 9 منٹ

ActivityResultLauncher Android Activity Result API کا ایک جزو ہے، جو androidx.activity لائبریری کے Activity 1.2.0 ورژن میں متعارف کرایا گیا۔ یہ فرسودہ طریقوں startActivityForResult اور onActivityResult کی جگہ لیتا ہے، جو Android SDK کے آغاز سے ہی اس کا حصہ تھے۔ Android Developers (2024) کے مطابق، نیا API Activity کے ساتھ مضبوط انحصار اور ٹائپ سیفٹی کی کمی کے مسائل کو ختم کرتا ہے۔ ActivityResultLauncher پہلے سے رجسٹر ہوتا ہے اور ان پٹ اور آؤٹ پٹ ڈیٹا کی سخت ٹائپنگ کے لیے Contract استعمال کرتا ہے۔

اہم نکات

  • ActivityResultLauncher — فرسودہ startActivityForResult کی بجائے Activity سے نتائج حاصل کرنے کے لیے نیا API
  • Contract — ایک آبجیکٹ جو کسی مخصوص منظر نامے کے لیے ان پٹ اور آؤٹ پٹ ڈیٹا کی قسم متعین کرتا ہے
  • رجسٹریشن launch کال کرنے سے پہلے registerForActivityResult کے ذریعے کی جاتی ہے
  • Callback ہدف Activity کے نتیجہ کے ساتھ ختم ہونے کے بعد بلایا جاتا ہے
  • API دستیاب Activity 1.2.0 سے Activity، Fragment اور Compose کے لیے

ActivityResultLauncher کیا ہے

ActivityResultLauncher androidx.activity.result پیکیج کی ایک کلاس ہے جو Activity شروع کرنے اور نتیجہ حاصل کرنے کے لیے ٹائپ سیف میکانزم فراہم کرتی ہے۔ Launcher registerForActivityResult طریقہ کے ذریعے بنایا جاتا ہے، جو دو پیرامیٹر لیتا ہے: Contract (ان پٹ اور آؤٹ پٹ اقسام کی وضاحت کرتا ہے) اور ActivityResultCallback (نتیجہ ہینڈلر)۔ رجسٹریشن کے بعد، launcher launch طریقہ کے ذریعے کال کرنے کے لیے تیار ہوتا ہے۔

پرانی API سے بنیادی فرق رجسٹریشن اور لانچ کی علیحدگی ہے۔ رجسٹریشن ابتدائی مرحلے (Activity.onCreate یا Fragment.onCreate) میں کی جاتی ہے، callback ایک بار launcher سے منسلک ہو جاتا ہے اور نتیجہ واپس آنے پر اس کے چلنے کی ضمانت ہوتی ہے۔ یہ اس مسئلے کو ختم کرتا ہے جہاں onActivityResult غیر متوقع ترتیب میں یا تباہ شدہ Activity پر چلتا تھا۔

ActivityResultLauncher تمام منظرناموں کو سپورٹ کرتا ہے جو پہلے onActivityResult کے ذریعے سنبھالے جاتے تھے: کیمرہ شروع کرنا، گیلری، رابطوں کی درخواست، اجازتیں اور حسب ضرورت Activity۔ مزید برآں، API قابل توسیع ہے: ڈویلپر Activity کے درمیان ڈیٹا کے تبادلے کے مخصوص منظرناموں کے لیے حسب ضرورت Contract بنا سکتے ہیں۔

Activity Result API نے startActivityForResult کی جگہ کیوں لی

startActivityForResult API Level 1 (2008) سے Android SDK کا حصہ تھا اور 12 سال سے زائد عرصے تک Activity سے نتیجہ حاصل کرنے کا بنیادی طریقہ رہا۔ تاہم، اس طریقہ میں بنیادی خامیاں تھیں جنہیں Google نے Activity Result API میں حل کیا۔ آئیے اہم مسائل اور نئے API کے انہیں حل کرنے کے طریقے دیکھتے ہیں۔

مسئلہ 1: Activity کے ساتھ مضبوط انحصار

startActivityForResult طریقہ requestCode کے ذریعے Activity اور Fragment سے منسلک ہے — ایک صوابدیدی عدد جو onActivityResult کو بھیجا جاتا ہے۔ ڈویلپر دستی طور پر کوڈ کو شروع کردہ آپریشن سے ملاتا تھا، جس سے کوڈ کے دوبارہ استعمال اور وراثت میں غلطیاں ہوتی تھیں۔ ActivityResultLauncher requestCode کو مکمل طور پر ختم کر دیتا ہے: callback رجسٹریشن کے وقت ایک مخصوص launcher سے منسلک ہوتا ہے اور صرف اس کے لیے بلایا جاتا ہے۔

مسئلہ 2: اسکرین گھمانے پر نتیجہ کا نقصان

ترتیب کی تبدیلیوں (اسکرین گھمانا، زبان تبدیل کرنا) کے دوران، Activity دوبارہ بنائی جاتی تھی اور onActivityResult چل نہیں سکتا تھا — callback کھو جاتا تھا۔ Activity Result API SavedStateRegistry کے ذریعے خود بخود launcher کی حالت محفوظ اور بحال کرتی ہے، جو Activity کی دوبارہ تخلیق کے بعد بھی نتیجہ حاصل کرنے کی ضمانت دیتی ہے۔

مسئلہ 3: ٹائپ سیفٹی کی کمی

پرانی API نتیجہ Bundle کے ساتھ Intent کے ذریعے بھیجتی تھی، جہاں کلیوں اور ڈیٹا کی اقسام کی کمپائلر کے ذریعے جانچ نہیں کی جاتی تھی۔ Activity Result API Contract استعمال کرتی ہے — ایک عام انٹرفیس جو ان پٹ ڈیٹا کی قسم (I) اور نتیجہ کی قسم (O) متعین کرتا ہے۔ قسم کی عدم مطابقت کی غلطیاں رن ٹائم کے بجائے کمپائل ٹائم پر پکڑی جاتی ہیں۔

خصوصیتstartActivityForResultActivityResultLauncher
RequestCodeدستی انتظام درکارخودکار، درکار نہیں
ٹائپ سیفٹینہیںعام Contract
گھمانے پر محفوظ کرناکھو جاتا ہےSavedStateRegistry
کم از کم APIAPI Level 1Activity 1.2.0
Compose میں استعمالتعاون یافتہ نہیںrememberLauncherForActivityResult

Activity Result API کے اہم کنٹریکٹ

Contract ActivityResultContract<I, O> انٹرفیس ہے، جو متعین کرتا ہے کہ Activity کیسے شروع کی جائے اور نتیجہ کی تشریح کیسے کی جائے۔ Google عام منظرناموں کے لیے بلٹ ان کنٹریکٹ کا ایک سیٹ فراہم کرتا ہے جو زیادہ تر ڈویلپر کی ضروریات کو پورا کرتا ہے۔

StartIntentSenderForResult

StartIntentSenderForResult — IntentSender شروع کرنے کے لیے ایک بنیادی کنٹریکٹ۔ سسٹم منظرناموں میں استعمال ہوتا ہے، مثال کے طور پر Google Sign-In کے ذریعے اجازت یا Google Pay کے ذریعے ادائیگی کرتے وقت۔ ان پٹ پیرامیٹر PendingIntent ہے، آؤٹ پٹ کوڈ اور Intent کے ساتھ ActivityResult ہے۔

RequestMultiplePermissions

RequestMultiplePermissions — Android 6.0+ پر بیک وقت متعدد اجازتوں کی درخواست کرنے کے لیے کنٹریکٹ۔ ان پٹ پیرامیٹر اجازت کے ناموں کی String صف ہے، آؤٹ پٹ ہر درخواست کے نتیجہ کے ساتھ Map<String, Boolean> ہے۔ پہلے اس کے لیے درخواست کوڈز کو ملاتے ہوئے onRequestPermissionsResult میں دستی تجزیہ درکار تھا۔

TakePicture اور TakeVideo

TakePicture — سسٹم کیمرہ کے ذریعے تصویر لینے کے لیے کنٹریکٹ۔ ان پٹ وہ Uri ہے جہاں تصویر محفوظ کرنی ہے، آؤٹ پٹ Boolean (کامیابی) ہے۔ TakeVideo ویڈیو کے ساتھ اسی طرح کام کرتا ہے۔ یہ کنٹریکٹ مختلف آلات پر غیر مستحکم رویے کے ساتھ فرسودہ MediaStore.ACTION_IMAGE_CAPTURE کی جگہ لیتے ہیں۔

GetContent اور OpenDocument

GetContent — سسٹم پکر کے ذریعے مواد منتخب کرنے کے لیے کنٹریکٹ۔ ان پٹ MIME قسم ہے (مثلاً image/*)، آؤٹ پٹ منتخب فائل کا Uri ہے۔ OpenDocument متعدد انتخاب اور دستاویز کی اقسام کے لحاظ سے فلٹرنگ کو سپورٹ کرنے میں مختلف ہے۔ دونوں کنٹریکٹ SAF (Storage Access Framework) کے ذریعے کام کرتے ہیں۔

CreateDocument اور OpenDocumentTree

CreateDocument — سسٹم ڈائیلاگ کے ذریعے نیا دستاویز بنانے کے لیے کنٹریکٹ۔ صارف نام اور فولڈر منتخب کرتا ہے، سسٹم لکھنے کے لیے Uri واپس کرتا ہے۔ OpenDocumentTree پوری ڈائریکٹری تک رسائی فراہم کرتا ہے — صارف ایک فولڈر منتخب کرتا ہے، اور ایپ اندر کی تمام فائلوں کو پڑھنے اور لکھنے کے لیے tree-uri حاصل کرتی ہے۔

Activity اور Fragment میں استعمال

کلاسک Android میں ActivityResultLauncher استعمال کرنے کا بنیادی نمونہ دو مراحل پر مشتمل ہے: ابتدا میں registerForActivityResult کے ذریعے رجسٹریشن اور صارف کے عمل کے جواب میں launch کال۔ آئیے گیلری سے تصویر منتخب کرنے کی ایک عام مثال دیکھتے ہیں۔

Activity میں رجسٹریشن اور لانچ

Launcher کو Activity کے onCreate میں رجسٹر کریں — یہ یقینی بناتا ہے کہ کسی بھی ممکنہ کال سے پہلے callback تیار ہو۔ کبھی بھی لانچ کرنے سے فوراً پہلے launcher رجسٹر نہ کریں — یہ API کنٹریکٹ کی خلاف ورزی ہے اور Activity کی دوبارہ تخلیق پر نتیجہ کے نقصان کا سبب بن سکتا ہے۔

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 میں استعمال

ایک Fragment میں، رجسٹریشن onCreate، onAttach یا onCreateView میں ابتدا پر کی جاتی ہے۔ FragmentActivity والدین Activity کے ذریعے launcher بھیجتی ہے، لہذا نتیجہ Activity کی بجائے Fragment کے اندر پروسیس ہوتا ہے۔ یہ onActivityResult کے مقابلے میں انکیپسولیشن کو بہتر بناتا ہے، جہاں تمام Fragment کے تمام نتائج ایک Activity طریقہ میں جمع ہوتے تھے۔

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

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

Jetpack Compose میں ActivityResultLauncher

Jetpack Compose Activity Result API کے لیے ایک خاص composable فنکشن فراہم کرتا ہے — rememberLauncherForActivityResult۔ کلاسک طریقہ کے برعکس، Compose میں launcher remember کے ذریعے composable لائف سائیکل سے منسلک ایک آبجیکٹ کے طور پر بنایا جاتا ہے۔ یہ Activity یا Fragment تک براہ راست رسائی کے بغیر مکمل طور پر اعلانیہ انداز میں Activity Result API استعمال کرنے کی اجازت دیتا ہے۔

rememberLauncherForActivityResult

rememberLauncherForActivityResult Contract اور callback لیتا ہے، اور ActivityResultLauncher واپس کرتا ہے۔ دوبارہ ترکیب کے دوران launcher محفوظ رہتا ہے اور ترکیب چھوڑنے پر خود بخود صاف ہو جاتا ہے۔ launch کال کسی واقعے کے جواب میں ہوتی ہے — مثال کے طور پر، بٹن کلک یا حالت کی تبدیلی۔

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

    Button(onClick = { launcher.launch("image/*") }) {
        Text("تصویر منتخب کریں")
    }
}

Compose میں اجازت کا انتظام

Compose میں اجازت کی درخواستیں بھی RequestPermission یا RequestMultiplePermissions کنٹریکٹ کے ساتھ rememberLauncherForActivityResult کے ذریعے کی جاتی ہیں۔ Google accompanist-permissions استعمال کرنے کی سفارش کرتا ہے، لیکن اندرونی طور پر یہ بھی Activity Result API استعمال کرتا ہے۔ اجازت کی حالت کو ٹریک کرنے کے لیے، حالت کو remember یا ViewModel میں ذخیرہ کرنا آسان ہے۔

عام غلطیاں اور بہترین طرز عمل

Activity Result API نے پرانے طریقہ کے بہت سے مسائل ختم کر دیے، لیکن غلط استعمال نئی قسم کی غلطیوں کا سبب بن سکتا ہے۔ آئیے سب سے عام مسائل اور ان سے بچنے کے طریقے دیکھتے ہیں۔

غلطی: lambda یا coroutine کے اندر رجسٹریشن

Launcher کی رجسٹریشن جزو کی ابتدا کے دوران کی جانی چاہیے — Activity کے onCreate یا Fragment کے ابتداکار میں۔ اگر آپ launcher کو lambda، callback یا coroutine کے اندر رجسٹر کرتے ہیں، تو Activity کی دوبارہ تخلیق پر رجسٹریشن دوبارہ ہو سکتی ہے اور پرانا launcher نتیجہ سے رابطہ کھو دے گا۔

غلطی: ایک ہی کلید کے ساتھ متعدد launchers رجسٹر کرنا

ہر launcher حالت محفوظ کرنے کے لیے ایک منفرد کلید حاصل کرتا ہے۔ اگر آپ ایک جزو میں ایک ہی Contract کے ساتھ دو launchers رجسٹر کرتے ہیں، تو SavedStateRegistry ایک کی حالت کو دوسرے سے اوور رائٹ کر سکتا ہے۔ Android Studio lint اصول UnnecessaryRegisterForActivityResult کے ذریعے اس بارے میں خبردار کرتا ہے، لیکن انفرادیت کو دستی طور پر کنٹرول کرنا بہتر ہے۔

بہترین طرز عمل: ہمیشہ null نتیجہ سنبھالیں

صارف عمل کو منسوخ کر سکتا ہے — سسٹم کا واپس بٹن دبا سکتا ہے، ایپ کو چھوٹا کر سکتا ہے، یا کسی دوسری ایپ پر جا سکتا ہے۔ اس صورت میں، callback null یا RESULT_CANCELED کے ساتھ ActivityResult وصول کرے گا۔ NullPointerException سے بچنے کے لیے استعمال کرنے سے پہلے ہمیشہ null کے لیے نتیجہ چیک کریں۔

بہترین طرز عمل: دوبارہ قابل استعمال منطق کے لیے حسب ضرورت Contract

اگر آپ کی ایپ بار بار اسی طرح کے منظرنامے شروع کرتی ہے — مثال کے طور پر، ایک رابطہ منتخب کرنا اور نام اور فون واپس کرنا — تو ایک حسب ضرورت Contract بنائیں۔ یہ کوڈ کی پڑھنے کی اہلیت کو بہتر بناتا ہے اور لانچ اور نتیجہ سنبھالنے کی منطق میں مرکزی تبدیلیوں کی اجازت دیتا ہے۔

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

اکثر پوچھے گئے سوالات

کیا ViewModel میں ActivityResultLauncher استعمال کیا جا سکتا ہے؟

نہیں — ActivityResultLauncher کو رجسٹریشن کے لیے Activity یا Fragment کے سیاق و سباق کی ضرورت ہے۔ ViewModel کو صرف حالت ذخیرہ کرنے کے لیے استعمال کریں، اور launcher کو Activity یا Fragment میں بنائیں اور نتیجہ ViewModel کو بھیجیں۔

Activity Result API کے لیے کم از کم SDK کیا درکار ہے؟

Activity Result API لائبریری activity-ktx 1.2.0 سے دستیاب ہے۔ کم از کم SDK API Level 14 (Android 4.0) ہے، لیکن زیادہ تر کنٹریکٹ صرف API Level 19+ پر کام کرتے ہیں۔

اگر نتیجہ حاصل کرنے سے پہلے launch دو بار بلایا جائے تو کیا ہوتا ہے؟

پہلی کارروائی مکمل ہونے سے پہلے launch کی بار بار کال نظر انداز کر دی جائے گی۔ Activity Result API متوازی لانچوں کو سپورٹ نہیں کرتی — نئی کال کرنے سے پہلے پہلی کارروائی سے callback کا انتظار کریں۔

پرانے کوڈ میں onActivityResult کو کیسے تبدیل کیا جائے؟

منتقلی مناسب Contract کے ساتھ startActivityForResult کال کو registerForActivityResult سے تبدیل کرکے کی جاتی ہے۔ onActivityResult کو ہٹائیں اور نتیجہ کو launcher callback میں سنبھالیں۔ Google Android Developers دستاویزات میں منتقلی گائیڈ فراہم کرتا ہے۔

کیا ActivityResultLauncher ML Kit یا Barcode Scanner جیسی لائبریریوں کے ساتھ کام کرتا ہے؟

ہاں، بہت سی لائبریریاں ActivityResultContracts کے ذریعے انضمام کو سپورٹ کرتی ہیں۔ مثال کے طور پر، ML Kit Barcode Scanner اسکینر شروع کرنے کے لیے StartIntentSenderForResult استعمال کرتی ہے۔ مخصوص لائبریری کی دستاویزات دیکھیں۔

خلاصہ

  • ActivityResultLauncher — فرسودہ startActivityForResult کی جگہ لینے والا جدید ٹائپ سیف API
  • Contract ان پٹ اور آؤٹ پٹ ڈیٹا کی اقسام متعین کرتا ہے، دستی requestCode ملانے کو ختم کرتا ہے
  • رجسٹریشن ابتدا پر کی جاتی ہے، نتیجہ callback کے ذریعے فراہم کرنے کی ضمانت ہے
  • بلٹ ان کنٹریکٹ کیمرہ، گیلری، اجازتیں، دستاویزات اور رابطوں کا احاطہ کرتے ہیں
  • Jetpack Compose API کے ساتھ کام کرنے کے لیے rememberLauncherForActivityResult استعمال کرتا ہے
  • حسب ضرورت Contract اجزاء کے درمیان لانچ منطق کو دوبارہ استعمال کرنے کی اجازت دیتے ہیں
  • API SavedStateRegistry کے ذریعے ترتیب کی تبدیلیوں کے دوران حالت محفوظ رکھتا ہے

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں