لتنفيذ عمليات الشبكة في تطبيقك، يجب أن يتضمّن البيان الأذونات التالية:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
أفضل الممارسات لضمان أمان الاتصالات على الشبكة
قبل إضافة وظيفة التواصل مع الشبكة إلى تطبيقك، عليك التأكّد من أمان البيانات والمعلومات داخل تطبيقك عند نقلها عبر الشبكة. اتّبِع أفضل الممارسات التالية لأمان الشبكات:
- الحدّ من مقدار بيانات المستخدِم الحسّاسة أو الشخصية التي تُرسِلها عبر الشبكة
- أرسِل جميع حركات بيانات الشبكة من تطبيقك عبر طبقة المقابس الآمنة.
- يمكنك إنشاء إعداد لأمان الشبكة، ما يتيح لتطبيقك الوثوق في مراجع تصديق مخصَّصة أو تقييد مجموعة من مراجع التصديق (CA) للنظام التي يثق بها لإجراء اتصال آمن.
لمزيد من المعلومات حول كيفية تطبيق مبادئ الشبكات الآمنة، يُرجى الاطّلاع على نصائح أمان الشبكات.
اختيار برنامج HTTP
تستخدم معظم التطبيقات المتصلة بالشبكة بروتوكول HTTP لإرسال البيانات واستلامها. يتضمّن منصّة Android
برنامج العميل
HttpsURLConnection
،
الذي يتيح استخدام بروتوكول TLS وعمليات التحميل والتنزيل عبر البث ووقت الاستراحة القابل للضبط
وIPv6 وميزة تجميع الاتصالات.
تتوفّر أيضًا مكتبات تابعة لجهات خارجية تقدّم واجهات برمجة تطبيقات ذات مستوى أعلى لعمليات الشبكات. وتتيح هذه الميزات العديد من الميزات الملائمة، مثل تسلسل نصوص الطلبات وإلغاء تسلسل نصوص الاستجابة.
- عملية التحديث: وهو عميل HTTP آمن من حيث النوع لـ JVM من Square، وهو مبني على OkHttp. تتيح لك ميزة التحديث التلقائي إنشاء واجهة عميل بشكل صريح وتدعم العديد من مكتبات التسلسل.
- Ktor: برنامج HTTP من JetBrains، تم تصميمه بالكامل للغة Kotlin وتشغيل من خلال الكوروتينات. يتوافق Ktor مع العديد من المحرّكات و المشفّرات والمنصات.
حلّ طلبات البحث في نظام أسماء النطاقات
تتوفّر في الأجهزة التي تعمل بالإصدار 10 من نظام التشغيل Android (المستوى 29 من واجهة برمجة التطبيقات) والإصدارات الأحدث ميزة مدمجة ل
عمليات البحث المخصّصة في نظام أسماء النطاقات من خلال عمليات البحث النصية الواضحة ووضع DNS-over-TLS.
توفّر واجهة برمجة التطبيقات DnsResolver
حلًا عامًا
غير متزامن، ما يتيح لك البحث عن SRV
وNAPTR
وأنواع
السجلّات الأخرى. ويُترك للتطبيق تحليل الردّ.
على الأجهزة التي تعمل بنظام التشغيل Android 9 (المستوى 28 من واجهة برمجة التطبيقات) والإصدارات الأقدم، تتيح أداة حل نظام أسماء النطاقات للنظام الأساسي
استخدام سجلّات A
وAAAA
فقط. يتيح لك ذلك البحث عن عناوين IP
المرتبطة باسم معيّن، ولكنه لا يتيح استخدام أي أنواع أخرى من السجلّات.
بالنسبة إلى التطبيقات المستندة إلى NDK، يُرجى الاطّلاع على
android_res_nsend
.
تجميع عمليات الشبكة في مستودع
لتبسيط عملية تنفيذ عمليات الشبكة والحدّ من تكرار الرمز المبرمَج في أجزاء مختلفة من تطبيقك، يمكنك استخدام ملف نموذج تصميم المستودع. المستودع هو فئة تعالج عمليات البيانات وتوفّر واجهة برمجة تطبيقات برمجية مختصرة وواضحة لبعض البيانات أو الموارد المحدّدة.
يمكنك استخدام Retrofit لتعريف واجهة تحدّد طريقة HTTP و عنوان URL والوسيطات ونوع الاستجابة لعمليات الشبكة، كما هو موضّح في المثال التالي:
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
تنفيذ ميزة "المعالجة المتعدّدة المواضيع" إمّا باستخدام وظائف coroutines أو باستخدام الدالة 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 } }); } }
قراءة الأدلة ذات الصلة
لمزيد من المعلومات عن هذا الموضوع، اطّلِع على الأدلة التالية ذات الصلة:
- تقليل استهلاك البطارية للشبكة: نظرة عامة
- تقليل تأثير التحديثات العادية
- المحتوى المستنِد إلى الويب
- أساسيات التطبيق
- دليل بنية التطبيقات