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-এর মাধ্যমে পরিচালিত হত: ক্যামেরা, গ্যালারি চালু করা, পরিচিতি, অনুমতি এবং কাস্টম Activities অনুরোধ করা। তাছাড়া, API প্রসারণযোগ্য: ডেভেলপাররা Activities-এর মধ্যে ডেটা বিনিময়ের নির্দিষ্ট পরিস্থিতির জন্য কাস্টম Contract তৈরি করতে পারেন।

কেন Activity Result API startActivityForResult প্রতিস্থাপন করেছে

startActivityForResult API Level 1 (2008) থেকে Android SDK-এর অংশ ছিল এবং ১২ বছরেরও বেশি সময় ধরে Activity থেকে ফলাফল পাওয়ার প্রধান উপায় ছিল। তবে, এই পদ্ধতিতে মৌলিক ত্রুটি ছিল যা Google Activity Result API-তে সমাধান করেছে। আসুন মূল সমস্যা এবং নতুন API কীভাবে সেগুলি সমাধান করে তা দেখি।

সমস্যা ১: Activity-এর সাথে শক্ত সংযোগ

startActivityForResult পদ্ধতি requestCode-এর মাধ্যমে Activity এবং Fragment-এর সাথে আবদ্ধ — একটি নির্বিচার পূর্ণসংখ্যা যা onActivityResult-এ পাঠানো হয়। ডেভেলপার ম্যানুয়ালি কোডটিকে চালু করা অপারেশনের সাথে মেলাত, যা কোড পুনঃব্যবহার এবং উত্তরাধিকারে ত্রুটির দিকে পরিচালিত করত। ActivityResultLauncher সম্পূর্ণরূপে requestCode বাদ দেয়: callback নিবন্ধনের সময় একটি নির্দিষ্ট launcher-এর সাথে আবদ্ধ হয় এবং শুধুমাত্র তার জন্য আহ্বান করা হয়।

সমস্যা ২: স্ক্রিন ঘোরানোর সময় ফলাফল হারানো

কনফিগারেশন পরিবর্তনের সময় (স্ক্রিন ঘোরানো, ভাষা পরিবর্তন), Activity পুনরায় তৈরি হত এবং onActivityResult কার্যকর নাও হতে পারত — callback হারিয়ে যেত। Activity Result API SavedStateRegistry-এর মাধ্যমে স্বয়ংক্রিয়ভাবে launcher অবস্থা সংরক্ষণ এবং পুনরুদ্ধার করে, যা Activity পুনর্নির্মাণের পরেও ফলাফল পাওয়ার নিশ্চয়তা দেয়।

সমস্যা ৩: টাইপ নিরাপত্তার অভাব

পুরানো 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 আরম্ভকর্তায়। যদি আপনি lambda, callback বা coroutine-এর ভিতরে launcher নিবন্ধন করেন, Activity পুনর্নির্মাণে নিবন্ধন আবার করা হতে পারে এবং পুরানো launcher ফলাফলের সাথে সংযোগ হারাবে।

ভুল: একই কী দিয়ে একাধিক launcher নিবন্ধন করা

প্রতিটি launcher অবস্থা সংরক্ষণের জন্য একটি অনন্য কী পায়। যদি আপনি একটি উপাদানে একই Contract-এর সাথে দুটি launcher নিবন্ধন করেন, 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 ব্যবহার করুন, এবং Activity বা Fragment-এ launcher তৈরি করুন এবং ফলাফল 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 অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন