नेटवर्क से कनेक्ट करें

अपने ऐप्लिकेशन में नेटवर्क कार्रवाइयां करने के लिए, आपके मेनिफ़ेस्ट में यह जानकारी शामिल होनी चाहिए ये अनुमतियां दी जाएंगी:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

सुरक्षित नेटवर्क कम्यूनिकेशन के लिए सबसे सही तरीके

अपने ऐप्लिकेशन में नेटवर्किंग की सुविधा जोड़ने से पहले, आपको यह पक्का करना होगा कि नेटवर्क पर डेटा और जानकारी भेजने के दौरान, वे सुरक्षित रहें. ऐसा करने के लिए, नेटवर्किंग सुरक्षा के इन सबसे सही तरीकों को अपनाएं:

  • नेटवर्क पर भेजे जाने वाले, उपयोगकर्ता के संवेदनशील या निजी डेटा की मात्रा कम करें.
  • अपने ऐप्लिकेशन का सारा नेटवर्क ट्रैफ़िक इस पर भेजें एसएसएल.
  • नेटवर्क सुरक्षा बनाएं कॉन्फ़िगरेशन, जिसकी मदद से आपका ऐप्लिकेशन कस्टम सर्टिफ़िकेट अथॉरिटी (सीए) पर भरोसा करें या सिस्टम सीए के सेट पर पाबंदी लगाएं सुरक्षित तरीके से बातचीत करने के लिए, इसे भरोसेमंद माना जाता है.

सुरक्षित नेटवर्किंग सिद्धांत लागू करने के तरीके के बारे में ज़्यादा जानकारी के लिए, नेटवर्क सुरक्षा के सुझाव देखें.

कोई एचटीटीपी क्लाइंट चुनें

नेटवर्क से कनेक्ट किए गए ज़्यादातर ऐप्लिकेशन, डेटा भेजने और पाने के लिए एचटीटीपी का इस्तेमाल करते हैं. Android प्लैटफ़ॉर्म में HttpsURLConnection क्लाइंट, जो TLS, स्ट्रीमिंग अपलोड और डाउनलोड, कॉन्फ़िगर किए जा सकने वाले टाइम आउट, आईपीवी6 और कनेक्शन पूलिंग.

नेटवर्किंग कार्रवाइयों के लिए ऊपर के लेवल के एपीआई ऑफ़र करने वाली तीसरे पक्ष की लाइब्रेरी यह भी देखा जा सकता है. इनके साथ कई सुविधाएं मिलती हैं, जैसे कि अनुरोध के मुख्य भाग को क्रम से लगाना और रिस्पॉन्स बॉडी को डीसीरियलाइज़ेशन.

  • Retrofit: Square का यह एचटीटीपी क्लाइंट, जेवीएम के लिए सुरक्षित है. इसे OkHttp के आधार पर बनाया गया है. Retrofit आपको एलान के तौर पर क्लाइंट इंटरफ़ेस बनाता है और कई सीरियलाइज़ेशन लाइब्रेरी.
  • Ktor: JetBrains का एक एचटीटीपी क्लाइंट, जिसे बनाया गया है जो कोरूटीन की मदद से काम करते हैं. Ktor अलग-अलग इंजन के साथ काम करता है. सीरियलाइज़र, और प्लैटफ़ॉर्म.

डीएनएस क्वेरी हल करें

Android 10 (एपीआई लेवल 29) और उसके बाद के वर्शन वाले डिवाइसों में, Android 10 के साथ काम करने की सुविधा पहले से मौजूद होती है क्लियरटेक्स्ट लुकअप और डीएनएस-ओवर-टीएलएस मोड, दोनों का इस्तेमाल करके खास तरह के डीएनएस लुकअप का इस्तेमाल करता है. 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
            }
        });
    }
}

इस विषय के बारे में ज़्यादा जानने के लिए, नीचे दी गई मिलती-जुलती गाइड देखें: