Activity क्लास, Android ऐप्लिकेशन का एक अहम कॉम्पोनेंट है. साथ ही, ऐक्टिविटी को लॉन्च और एक साथ रखने का तरीका, प्लैटफ़ॉर्म के ऐप्लिकेशन मॉडल का एक बुनियादी हिस्सा है. प्रोग्रामिंग पैराडाइम में, ऐप्लिकेशन को main तरीके से लॉन्च किया जाता है. हालांकि, Android सिस्टम, Activity इंस्टेंस में कोड शुरू करता है. इसके लिए, वह खास कॉलबैक तरीकों का इस्तेमाल करता है. ये तरीके, ऐप्लिकेशन के लाइफ़साइकल के खास चरणों से जुड़े होते हैं.
इस दस्तावेज़ में, गतिविधियों के कॉन्सेप्ट के बारे में बताया गया है. इसके बाद, इनके साथ काम करने के बारे में कुछ सामान्य दिशा-निर्देश दिए गए हैं. अपने ऐप्लिकेशन का आर्किटेक्चर तैयार करने के सबसे सही तरीकों के बारे में ज़्यादा जानकारी के लिए, ऐप्लिकेशन के आर्किटेक्चर की गाइड देखें.
गतिविधियों के बारे में जानकारी
मोबाइल ऐप्लिकेशन पर मिलने वाला अनुभव, डेस्कटॉप पर मिलने वाले अनुभव से अलग होता है. ऐसा इसलिए, क्योंकि ऐप्लिकेशन के साथ उपयोगकर्ता का इंटरैक्शन हमेशा एक ही जगह से शुरू नहीं होता. इसके बजाय, उपयोगकर्ता का सफ़र अक्सर गैर-निर्धारित तरीके से शुरू होता है. उदाहरण के लिए, होम स्क्रीन से ईमेल ऐप्लिकेशन खोलने पर, आपको ईमेल की सूची दिख सकती है. इसके उलट, अगर किसी सोशल मीडिया ऐप्लिकेशन का इस्तेमाल किया जा रहा है, तो वह आपके ईमेल ऐप्लिकेशन को लॉन्च कर सकता है. ऐसे में, आपको ईमेल लिखने के लिए सीधे ईमेल ऐप्लिकेशन की स्क्रीन पर ले जाया जा सकता है.
Activity क्लास को इस पैराडाइम को आसान बनाने के लिए डिज़ाइन किया गया है. जब कोई ऐप्लिकेशन किसी दूसरे ऐप्लिकेशन को शुरू करता है, तो शुरू करने वाला ऐप्लिकेशन, दूसरे ऐप्लिकेशन में किसी ऐक्टिविटी को शुरू करता है. ऐसा पूरे ऐप्लिकेशन को शुरू करने के बजाय किया जाता है. इस तरह, ऐक्टिविटी, ऐप्लिकेशन के लिए उपयोगकर्ता से इंटरैक्ट करने का एंट्री पॉइंट होती है. किसी गतिविधि को Activity क्लास की सबक्लास के तौर पर लागू किया जाता है.
ऐक्टिविटी, वह विंडो होती है जिसमें ऐप्लिकेशन अपना यूज़र इंटरफ़ेस (यूआई) दिखाता है. यह विंडो आम तौर पर पूरी स्क्रीन पर दिखती है. हालांकि, यह स्क्रीन से छोटी भी हो सकती है और अन्य विंडो के सबसे ऊपर दिख सकती है.
आम तौर पर, किसी ऐप्लिकेशन में एक ऐक्टिविटी को मुख्य ऐक्टिविटी के तौर पर सेट किया जाता है. यह वह पहली स्क्रीन होती है जो उपयोगकर्ता को ऐप्लिकेशन लॉन्च करने पर दिखती है. Compose के आधुनिक ऐप्लिकेशन में, यह सिर्फ़ ज़रूरी ऐक्टिविटी होती है, क्योंकि यह व्यू हैरारकी के बजाय सिंगल-ऐक्टिविटी आर्किटेक्चर में कंपोज़ेबल होस्ट करती है. स्क्रीन के लिए ऐप्लिकेशन में कई गतिविधियां होने के बजाय, ऐक्टिविटी होस्ट में कंपोज़ेबल कई नेविगेशन डेस्टिनेशन होते हैं.
अपने ऐप्लिकेशन में गतिविधियों का इस्तेमाल करने के लिए, आपको ऐप्लिकेशन के मेनिफ़ेस्ट में उनकी जानकारी रजिस्टर करनी होगी. साथ ही, गतिविधि के लाइफ़साइकल के बारे में जानना एक अच्छा तरीका है. इस दस्तावेज़ के बाकी हिस्से में इन विषयों के बारे में बताया गया है.
मेनिफ़ेस्ट कॉन्फ़िगर करना
ऐप्लिकेशन में गतिविधियों का इस्तेमाल करने के लिए, आपको मेनिफ़ेस्ट में गतिविधियों और उनके कुछ एट्रिब्यूट के बारे में बताना होगा.
गतिविधियों का एलान करना
अपनी गतिविधि के बारे में बताने के लिए, मेनिफ़ेस्ट फ़ाइल खोलें और <application> एलिमेंट के चाइल्ड के तौर पर <activity>
एलिमेंट जोड़ें. उदाहरण के लिए:
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
...
</manifest >
इस एलिमेंट के लिए सिर्फ़ android:name एट्रिब्यूट ज़रूरी है. यह एट्रिब्यूट, गतिविधि की क्लास का नाम बताता है. ऐसे एट्रिब्यूट भी जोड़े जा सकते हैं जो गतिविधि की विशेषताओं के बारे में बताते हैं. जैसे, लेबल, आइकॉन या यूज़र इंटरफ़ेस (यूआई) थीम. इन और अन्य एट्रिब्यूट के बारे में ज़्यादा जानने के लिए, <activity> एलिमेंट का रेफ़रंस दस्तावेज़ देखें.
इंटेंट फ़िल्टर के बारे में जानकारी देना
इंटेंट फ़िल्टर, Android प्लैटफ़ॉर्म की एक बहुत ही असरदार सुविधा है. ये न सिर्फ़ एक्सप्लिसिट अनुरोध के आधार पर, बल्कि इंप्लिसिट अनुरोध के आधार पर भी गतिविधि लॉन्च करने की सुविधा देते हैं. उदाहरण के लिए, साफ़ तौर पर किए गए अनुरोध में सिस्टम को यह निर्देश दिया जा सकता है कि "Gmail ऐप्लिकेशन में ईमेल भेजने की सुविधा शुरू करो". इसके उलट, इंप्लिसिट अनुरोध से सिस्टम को यह निर्देश मिलता है कि "किसी भी ऐसी गतिविधि में ईमेल भेजने की स्क्रीन शुरू करो जो यह काम कर सकती है." जब सिस्टम यूज़र इंटरफ़ेस (यूआई) किसी उपयोगकर्ता से पूछता है कि किसी टास्क को पूरा करने के लिए कौनसा ऐप्लिकेशन इस्तेमाल करना है, तो इसका मतलब है कि इंटेंट फ़िल्टर काम कर रहा है.
इस सुविधा का फ़ायदा पाने के लिए, <activity> एलिमेंट में <intent-filter> एट्रिब्यूट की वैल्यू दें. इस एलिमेंट की परिभाषा में <action> एलिमेंट शामिल होता है. साथ ही, इसमें <category> एलिमेंट और/या <data> एलिमेंट शामिल हो सकता है. ये एलिमेंट मिलकर, उस इंटेंट के टाइप के बारे में बताते हैं जिसके हिसाब से आपकी गतिविधि जवाब दे सकती है. उदाहरण के लिए, यहां दिए गए कोड स्निपेट में, ऐसी ऐक्टिविटी को कॉन्फ़िगर करने का तरीका बताया गया है जो टेक्स्ट डेटा और ईमेल भेजती है. साथ ही, ऐसा करने के लिए अन्य ऐक्टिविटी से अनुरोध पाती है:
<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="mailto" />
</intent-filter>
</activity>
इस उदाहरण में, <action> एलिमेंट से पता चलता है कि यह गतिविधि डेटा भेजती है. <category> एलिमेंट को DEFAULT के तौर पर एलान करने से, गतिविधि को लॉन्च करने के अनुरोध मिल सकते हैं. <data> एलिमेंट से, उस डेटा के टाइप के बारे में पता चलता है जिसे यह गतिविधि भेज सकती है. नीचे दिए गए कोड स्निपेट में, ईमेल लिखने के लिए ऊपर बताई गई गतिविधि को कॉल करने का तरीका दिखाया गया है:
fun composeEmail(addresses: Array<String>, subject: String) {
val intent = Intent(Intent.ACTION_SENDTO).apply {
data = Uri.parse("mailto:") // Only email apps handle this.
putExtra(Intent.EXTRA_EMAIL, addresses)
putExtra(Intent.EXTRA_SUBJECT, subject)
}
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
}
अगर आपको अपने ऐप्लिकेशन को सेल्फ-कंटेन्ड बनाना है और अन्य ऐप्लिकेशन को इसकी गतिविधियों को चालू करने की अनुमति नहीं देनी है, तो आपको किसी अन्य इंटेंट फ़िल्टर की ज़रूरत नहीं है. जिन गतिविधियों को आपको अन्य ऐप्लिकेशन के लिए उपलब्ध नहीं कराना है उनमें कोई इंटेंट फ़िल्टर नहीं होना चाहिए. साथ ही, उन्हें साफ़ तौर पर बताए गए इंटेंट का इस्तेमाल करके खुद शुरू किया जा सकता है. आपकी गतिविधियां, इंटेंट के हिसाब से कैसे काम कर सकती हैं, इस बारे में ज़्यादा जानने के लिए, इंटेंट और इंटेंट फ़िल्टर देखें.
आने वाले इंटेंट को मैनेज करना
यहां दिए गए उदाहरण में, एक साथ कई तरह के इंटेंट (जैसे कि एक टेक्स्ट शेयर करना, एक इमेज शेयर करना, और कई इमेज शेयर करना) को मैनेज करते समय, ऐक्टिविटी के लाइफ़साइकल को मैनेज करने का तरीका बताया गया है. इन अलग-अलग इनपुट को एक सेंट्रलाइज़्ड handleIntent फ़ंक्शन के ज़रिए रूट करके, यह पक्का किया जाता है कि ACTION_SEND और ACTION_SEND_MULTIPLE, दोनों कार्रवाइयों को सही तरीके से पार्स किया गया है. साथ ही, इन्हें ViewModel को सौंपा गया है, ताकि यूज़र इंटरफ़ेस (यूआई) को अपडेट किया जा सके.
class ExampleActivity : ComponentActivity() {
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handleIntent(intent)
setContent {
ComposeApp(viewModel)
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
handleIntent(intent)
}
private fun handleIntent(intent: Intent?) {
when (intent?.action) {
Intent.ACTION_SEND -> {
if ("text/plain" == intent.type) {
intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
viewModel.handleText(it) // Update UI to reflect text being shared
}
} else if (intent.type?.startsWith("image/") == true) {
(intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java))?.let {
viewModel.handleImage(it) // Update UI to reflect image being shared
}
}
}
Intent.ACTION_SEND_MULTIPLE -> {
if (intent.type?.startsWith("image/") == true) {
intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)?.let {
viewModel.handleMultipleImages(it) // Update UI to reflect multiple images being shared
}
} else {
// Handle other types
}
}
else -> {
// Handle other intents
}
}
}
}
अनुमतियों की जानकारी देना
मेनिफ़ेस्ट के <activity> टैग का इस्तेमाल करके, यह कंट्रोल किया जा सकता है कि कौनसे ऐप्लिकेशन कोई गतिविधि शुरू कर सकते हैं. कोई पेरेंट ऐक्टिविटी, चाइल्ड ऐक्टिविटी को तब तक लॉन्च नहीं कर सकती, जब तक कि दोनों ऐक्टिविटी के मेनिफ़ेस्ट में एक जैसी अनुमतियां न हों. अगर आपने किसी पैरंट गतिविधि के लिए <uses-permission> एलिमेंट का एलान किया है, तो हर चाइल्ड गतिविधि में उससे मिलता-जुलता <uses-permission> एलिमेंट होना चाहिए.
उदाहरण के लिए, अगर आपके ऐप्लिकेशन को सोशल मीडिया पर पोस्ट शेयर करने के लिए, SocialApp नाम के किसी काल्पनिक ऐप्लिकेशन का इस्तेमाल करना है, तो SocialApp को खुद ही यह अनुमति तय करनी होगी कि उसे कॉल करने वाले ऐप्लिकेशन के पास कौनसी अनुमति होनी चाहिए:
<manifest>
<activity android:name="...."
android:permission="com.google.socialapp.permission.SHARE_POST"
/>
इसके बाद, SocialApp को कॉल करने की अनुमति पाने के लिए, आपके ऐप्लिकेशन को SocialApp के मेनिफ़ेस्ट में सेट की गई अनुमति से मेल खाना चाहिए:
<manifest>
<uses-permission android:name="com.google.socialapp.permission.SHARE_POST" />
</manifest>
अनुमतियों और सुरक्षा के बारे में ज़्यादा जानकारी के लिए, सुरक्षा से जुड़ी चेकलिस्ट देखें.
ऐक्टिविटी के लाइफ़साइकल को मैनेज करना
अपनी लाइफ़साइकल के दौरान, कोई गतिविधि कई स्थितियों से गुज़रती है. स्टेट के बीच ट्रांज़िशन को मैनेज करने के लिए, कॉलबैक की सीरीज़ का इस्तेमाल किया जाता है. यहां दिए गए सेक्शन में इन कॉलबैक के बारे में बताया गया है. Compose ऐप्लिकेशन में, सीधे तौर पर इन कॉलबैक में हुक करने का सुझाव नहीं दिया जाता. इसके बजाय, स्थिति में होने वाले बदलावों को देखने के लिए, Lifecycle API का इस्तेमाल करें. ज़्यादा जानकारी के लिए, लाइफ़साइकल को Compose के साथ इंटिग्रेट करना लेख पढ़ें.
onCreate
आपको इस कॉलबैक को लागू करना होगा. यह कॉलबैक तब ट्रिगर होता है, जब सिस्टम आपकी ऐक्टिविटी बनाता है. आपके कोड में, गतिविधि के ज़रूरी कॉम्पोनेंट शुरू होने चाहिए: उदाहरण के लिए, आपके ऐप्लिकेशन को यहां व्यू बनाने चाहिए और डेटा को सूचियों से बाइंड करना चाहिए.
Compose ऐप्लिकेशन में, इस कॉलबैक का इस्तेमाल करके अपने होस्ट कंपोज़ेबल को सेट अप करें. इसके लिए, setContent का इस्तेमाल करें. इसे यहां दिखाया गया है:
class MyActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Text(text = stringResource(id = R.string.greeting))
}
}
}
onCreate के पूरा होने के बाद, अगला कॉलबैक हमेशा onStart होता है.
onStart
onCreate से बाहर निकलने पर, गतिविधि 'शुरू की गई' स्थिति में आ जाती है. इसके बाद, गतिविधि उपयोगकर्ता को दिखने लगती है. इस कॉलबैक में, ऐक्टिविटी को फ़ोरग्राउंड में लाने और इंटरैक्टिव बनाने के लिए, आखिरी तैयारियां शामिल होती हैं.
onResume
सिस्टम इस कॉलबैक को तब शुरू करता है, जब गतिविधि उपयोगकर्ता के साथ इंटरैक्ट करना शुरू करती है. इस समय, गतिविधि, ऐक्टिविटी स्टैक में सबसे ऊपर होती है और उपयोगकर्ता के सभी इनपुट कैप्चर करती है. ऐप्लिकेशन के ज़्यादातर मुख्य फ़ंक्शन, onResume तरीके से लागू किए जाते हैं.
onPause कॉलबैक हमेशा onResume के बाद होता है.
onPause
जब गतिविधि फ़ोकस खो देती है और रुकी हुई स्थिति में चली जाती है, तब सिस्टम onPause को कॉल करता है. यह स्थिति तब दिखती है, जब उपयोगकर्ता, उदाहरण के लिए, 'वापस जाएं' या हाल ही के बटन पर टैप करता है. जब सिस्टम आपकी गतिविधि के लिए onPause को कॉल करता है, तो इसका मतलब है कि आपकी गतिविधि अब भी कुछ हद तक दिख रही है. हालांकि, ज़्यादातर मामलों में यह इस बात का संकेत होता है कि उपयोगकर्ता गतिविधि छोड़ रहा है. साथ ही, गतिविधि जल्द ही रोकी गई या फिर से शुरू की गई स्थिति में आ जाएगी.
अगर उपयोगकर्ता को यूज़र इंटरफ़ेस (यूआई) अपडेट होने की उम्मीद है, तो रोके गए स्टेट में मौजूद गतिविधि, यूज़र इंटरफ़ेस (यूआई) को अपडेट करना जारी रख सकती है. इस तरह की गतिविधि के उदाहरणों में, नेविगेशन मैप स्क्रीन या मीडिया प्लेयर को चलाने वाली स्क्रीन दिखाना शामिल है. भले ही, ऐसी गतिविधियां फ़ोकस से हट जाएं, लेकिन उपयोगकर्ता को उम्मीद होती है कि उनका यूज़र इंटरफ़ेस (यूआई) अपडेट होता रहे.
आपको ऐप्लिकेशन या उपयोगकर्ता का डेटा सेव करने, नेटवर्क कॉल करने या डेटाबेस ट्रांज़ैक्शन करने के लिए, onPause का इस्तेमाल नहीं करना चाहिए. डेटा सेव करने के बारे में जानकारी के लिए, ट्रांज़िएंट यूज़र इंटरफ़ेस (यूआई) की स्थिति को सेव करना और वापस लाना लेख पढ़ें.
onPause के पूरा होने के बाद, अगला कॉलबैक onStop या onResume होता है. यह इस बात पर निर्भर करता है कि गतिविधि के रोके गए मोड में जाने के बाद क्या होता है.
onStop
जब ऐक्टिविटी उपयोगकर्ता को नहीं दिखती है, तब सिस्टम onStop को कॉल करता है. ऐसा इसलिए हो सकता है, क्योंकि गतिविधि बंद हो रही है, कोई नई गतिविधि शुरू हो रही है या कोई मौजूदा गतिविधि फिर से शुरू हो रही है और वह रुकी हुई गतिविधि को कवर कर रही है. इन सभी मामलों में, रुकी हुई गतिविधि अब नहीं दिखती.
सिस्टम जिस अगले कॉलबैक को कॉल करता है वह onRestart होता है. ऐसा तब होता है, जब गतिविधि उपयोगकर्ता के साथ इंटरैक्ट करने के लिए वापस आ रही हो. इसके अलावा, अगर यह गतिविधि पूरी तरह से बंद हो रही है, तो सिस्टम onDestroy को कॉल करता है.
onRestart
जब 'बंद है' स्थिति में मौजूद कोई गतिविधि फिर से शुरू होने वाली होती है, तब सिस्टम इस कॉलबैक को शुरू करता है. onRestart गतिविधि की स्थिति को उस समय से पहले जैसा कर देता है जब उसे रोका गया था.
इस कॉलबैक के बाद हमेशा onStart होता है.
onDestroy
सिस्टम इस कॉलबैक को तब शुरू करता है, जब किसी गतिविधि को बंद किया जाता है.
यह कॉलबैक, गतिविधि को मिलने वाला आखिरी कॉलबैक होता है. onDestroy का इस्तेमाल आम तौर पर यह पक्का करने के लिए किया जाता है कि गतिविधि के सभी संसाधन तब रिलीज़ हो जाएं, जब गतिविधि या उसे शामिल करने वाली प्रोसेस बंद हो जाए.
इस सेक्शन में, इस विषय के बारे में सिर्फ़ शुरुआती जानकारी दी गई है. गतिविधि के लाइफ़साइकल और उसके कॉलबैक के बारे में ज़्यादा जानकारी के लिए, गतिविधि का लाइफ़साइकल देखें.