अपने ऐप्लिकेशन में नेटवर्क से जुड़े काम करने के लिए, आपके मेनिफ़ेस्ट में ये अनुमतियां शामिल होनी चाहिए:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
सुरक्षित नेटवर्क कम्यूनिकेशन के लिए सबसे सही तरीके
अपने ऐप्लिकेशन में नेटवर्किंग की सुविधा जोड़ने से पहले, आपको यह पक्का करना होगा कि नेटवर्क पर डेटा और जानकारी ट्रांसमिट करते समय, आपके ऐप्लिकेशन में मौजूद डेटा और जानकारी सुरक्षित रहे. ऐसा करने के लिए, नेटवर्क की सुरक्षा से जुड़े ये सबसे सही तरीके अपनाएं:
- नेटवर्क पर, उपयोगकर्ता के संवेदनशील या निजी डेटा को कम से कम शेयर करें.
- अपने ऐप्लिकेशन से सभी नेटवर्क ट्रैफ़िक को एसएसएल पर भेजें.
- नेटवर्क की सुरक्षा का कॉन्फ़िगरेशन बनाएं. इससे आपके ऐप्लिकेशन को कस्टम सर्टिफ़िकेट अथॉरिटी (सीए) पर भरोसा करने या सिस्टम सीए के सेट को सीमित करने की सुविधा मिलती है. इससे सुरक्षित तरीके से कम्यूनिकेशन किया जा सकता है.
नेटवर्क को सुरक्षित रखने के सिद्धांतों को लागू करने के तरीके के बारे में ज़्यादा जानने के लिए, नेटवर्क की सुरक्षा से जुड़ी सलाह देखें.
कोई एचटीटीपी क्लाइंट चुनें
इंटरनेट से कनेक्ट होने वाले ज़्यादातर ऐप्लिकेशन, डेटा भेजने और पाने के लिए एचटीटीपी का इस्तेमाल करते हैं. Android प्लैटफ़ॉर्म में HttpsURLConnection क्लाइंट शामिल है. यह टीएलएस, स्ट्रीमिंग अपलोड और डाउनलोड, कॉन्फ़िगर किए जा सकने वाले टाइम आउट, IPv6, और कनेक्शन पूलिंग के साथ काम करता है.
नेटवर्किंग से जुड़े कामों के लिए, तीसरे पक्ष की ऐसी लाइब्रेरी भी उपलब्ध हैं जो बेहतर लेवल के एपीआई उपलब्ध कराती हैं. इनमें कई सुविधाएं मिलती हैं. जैसे, अनुरोध के मुख्य हिस्से को क्रम में लगाना और जवाब के मुख्य हिस्से को क्रम से हटाना.
- Retrofit: यह Square का एक टाइप-सेफ़ एचटीटीपी क्लाइंट है, जो जेवीएम के लिए है. इसे OkHttp के ऊपर बनाया गया है. Retrofit की मदद से, क्लाइंट इंटरफ़ेस को डिक्लेरेटिव तरीके से बनाया जा सकता है. साथ ही, इसमें कई सीरियलाइज़ेशन लाइब्रेरी का इस्तेमाल किया जा सकता है.
- Ktor: JetBrains का एक एचटीटीपी क्लाइंट, जिसे पूरी तरह से Kotlin के लिए बनाया गया है. यह कोरूटीन की मदद से काम करता है. Ktor, कई तरह के इंजन, सीरियलाइज़र, और प्लैटफ़ॉर्म के साथ काम करता है.
डीएनएस क्वेरी को हल करना
Android 10 (एपीआई लेवल 29) और इसके बाद के वर्शन वाले डिवाइसों में, खास डीएनएस लुकअप के लिए पहले से ही सहायता उपलब्ध होती है. इसके लिए, क्लियर टेक्स्ट लुकअप और डीएनएस-ओवर-टीएलएस मोड, दोनों का इस्तेमाल किया जाता है.
DnsResolver एपीआई, सामान्य और एसिंक्रोनस रिज़ॉल्यूशन उपलब्ध कराता है. इससे आपको SRV, NAPTR, और अन्य तरह के रिकॉर्ड देखने की सुविधा मिलती है. जवाब को पार्स करने का काम, ऐप्लिकेशन को करना होता है.
Android 9 (एपीआई लेवल 28) और इससे पहले के वर्शन वाले डिवाइसों पर, प्लैटफ़ॉर्म का डीएनएस रिज़ॉल्वर सिर्फ़ A और AAAA रिकॉर्ड के साथ काम करता है. इससे आपको किसी नाम से जुड़े आईपी पते खोजने में मदद मिलती है. हालांकि, इसमें किसी अन्य तरह के रिकॉर्ड का इस्तेमाल नहीं किया जा सकता.
एनडीके पर आधारित ऐप्लिकेशन के लिए, android_res_nsend देखें.
नेटवर्क से जुड़े ऑपरेशंस को रिपॉज़िटरी के साथ एनकैप्सुलेट करना
नेटवर्क से जुड़े काम करने की प्रोसेस को आसान बनाने और अपने ऐप्लिकेशन के अलग-अलग हिस्सों में कोड के डुप्लीकेट होने की समस्या को कम करने के लिए, रिपॉज़िटरी डिज़ाइन पैटर्न का इस्तेमाल किया जा सकता है. डेटा स्टोर करने की जगह एक क्लास होती है, जो डेटा से जुड़े कामों को मैनेज करती है. साथ ही, यह कुछ खास डेटा या संसाधन के लिए, एपीआई को साफ़ तौर पर ऐब्स्ट्रैक्ट करती है.
Retrofit का इस्तेमाल करके, ऐसा इंटरफ़ेस तय किया जा सकता है जो नेटवर्क से जुड़े कामों के लिए, एचटीटीपी मेथड, यूआरएल, आर्ग्युमेंट, और रिस्पॉन्स टाइप की जानकारी देता है. इसके लिए, यहां दिया गया उदाहरण देखें:
Kotlin
interface UserService { @GET("/users/{id}") suspend fun getUser(@Path("id") id: String): User }
Java
public interface UserService { @GET("/user/{id}") Call<User> getUserById(@Path("id") String id); }
रिपॉज़िटरी क्लास में, फ़ंक्शन नेटवर्क ऑपरेशन को एनकैप्सुलेट कर सकते हैं और उनके नतीजे दिखा सकते हैं. इस एनकैप्सुलेशन से यह पक्का होता है कि रिपॉज़िटरी को कॉल करने वाले कॉम्पोनेंट को यह जानने की ज़रूरत नहीं है कि डेटा कैसे सेव किया जाता है. डेटा को सेव करने के तरीके में होने वाले बदलावों को भी रिपॉज़िटरी क्लास में अलग रखा जाता है. उदाहरण के लिए, हो सकता है कि आपको एपीआई एंडपॉइंट में अपडेट जैसा कोई रिमोट बदलाव करना हो या लोकल कैश मेमोरी लागू करनी हो.
Kotlin
class UserRepository constructor( private val userService: UserService ) { suspend fun getUserById(id: String): User { return userService.getUser(id) } }
Java
class UserRepository { private UserService userService; public UserRepository( UserService userService ) { this.userService = userService; } public Call<User> getUserById(String id) { return userService.getUser(id); } }
यूज़र इंटरफ़ेस (यूआई) को रिस्पॉन्सिव बनाए रखने के लिए, मुख्य थ्रेड पर नेटवर्क से जुड़े ऑपरेशन न करें. डिफ़ॉल्ट रूप से, Android के लिए आपको मुख्य यूज़र इंटरफ़ेस (यूआई) थ्रेड के बजाय, किसी अन्य थ्रेड पर नेटवर्क से जुड़े काम करने होंगे. अगर मुख्य थ्रेड पर नेटवर्क से जुड़ी कार्रवाइयां करने की कोशिश की जाती है, तो NetworkOnMainThreadException थ्रो किया जाता है.
कोड के पिछले उदाहरण में, नेटवर्क ऑपरेशन असल में ट्रिगर नहीं होता है. UserRepository को कॉल करने वाले को, कोरूटीन या enqueue() फ़ंक्शन का इस्तेमाल करके थ्रेडिंग लागू करनी होगी. ज़्यादा जानकारी के लिए, कोडलैब इंटरनेट से डेटा पाना देखें. इसमें Kotlin कोरूटीन का इस्तेमाल करके, थ्रेडिंग को लागू करने का तरीका बताया गया है.
कॉन्फ़िगरेशन में होने वाले बदलावों को मैनेज करना
जब कॉन्फ़िगरेशन में कोई बदलाव होता है, जैसे कि स्क्रीन का रोटेशन, तो आपका फ़्रैगमेंट या ऐक्टिविटी खत्म हो जाती है और फिर से बनती है. फ़्रैगमेंट ऐक्टिविटी के लिए, इंस्टेंस स्टेट में सेव न किया गया डेटा मिट जाता है. इंस्टेंस स्टेट में सिर्फ़ कम डेटा सेव किया जा सकता है. अगर ऐसा होता है, तो आपको नेटवर्क के अनुरोध फिर से करने पड़ सकते हैं.
ViewModel का इस्तेमाल करके, कॉन्फ़िगरेशन में बदलाव होने पर भी डेटा को सुरक्षित रखा जा सकता है. ViewModel कॉम्पोनेंट को इस तरह से डिज़ाइन किया गया है कि वह यूज़र इंटरफ़ेस (यूआई) से जुड़े डेटा को लाइफ़साइकल के हिसाब से सेव और मैनेज कर सके. पिछले UserRepository का इस्तेमाल करके, ViewModel ज़रूरी नेटवर्क अनुरोध कर सकता है. साथ ही, LiveData का इस्तेमाल करके, आपके फ़्रैगमेंट या गतिविधि को नतीजा दे सकता है:
Kotlin
class MainViewModel constructor( savedStateHandle: SavedStateHandle, userRepository: UserRepository ) : ViewModel() { private val userId: String = savedStateHandle["uid"] ?: throw IllegalArgumentException("Missing user ID") private val _user = MutableLiveData<User>() val user = _user as LiveData<User> init { viewModelScope.launch { try { // Calling the repository is safe as it moves execution off // the main thread val user = userRepository.getUserById(userId) _user.value = user } catch (error: Exception) { // Show error message to user } } } }
Java
class MainViewModel extends ViewModel { private final MutableLiveData<User> _user = new MutableLiveData<>(); LiveData<User> user = (LiveData<User>) _user; public MainViewModel( SavedStateHandle savedStateHandle, UserRepository userRepository ) { String userId = savedStateHandle.get("uid"); Call<User> userCall = userRepository.getUserById(userId); userCall.enqueue(new Callback<User>() { @Override public void onResponse(Call<User> call, Response<User> response) { if (response.isSuccessful()) { _user.setValue(response.body()); } } @Override public void onFailure(Call<User> call, Throwable t) { // Show error message to user } }); } }
इससे जुड़ी गाइड पढ़ें
इस विषय के बारे में ज़्यादा जानने के लिए, इससे जुड़ी ये गाइड देखें:
- नेटवर्क की वजह से बैटरी खर्च होने की समस्या को कम करना: खास जानकारी
- नियमित अपडेट के असर को कम करना
- वेब पर आधारित कॉन्टेंट
- ऐप्लिकेशन से जुड़ी बुनियादी बातें
- ऐप्लिकेशन आर्किटेक्चर के बारे में गाइड