تجنُّب عمليات التنزيل غير المحسَّنة

يتمتع بعض مستخدمي تطبيقك بإمكانية الوصول إلى الإنترنت بشكل متقطع أو لديهم حدود على كمية المعلومات التي يمكنهم تنزيلها على أجهزتهم. يمكنك تشجيع المستخدمين على التفاعل مع تطبيقك بشكل متكرر من خلال تقليل كمية البيانات التي يحتاج تطبيقك إلى تنزيلها.

إنّ الطريقة الأساسية لتقليل عمليات التنزيل هي تنزيل ما تحتاج إليه فقط. في ما يتعلق بالبيانات، يعني ذلك تنفيذ واجهات برمجة تطبيقات REST التي تتيح لك تحديد معايير طلب البحث التي تحد من البيانات التي يتم عرضها باستخدام معلمات مثل وقت آخر تحديث لك.

وبالمثل، عند تنزيل الصور، من الأفضل تقليل حجم الصور من جهة الخادم، بدلاً من تنزيل الصور بالحجم الكامل التي يتم تقليلها على العميل.

تخزين استجابات HTTP مؤقتًا

من الأساليب المهمة الأخرى تجنُّب تنزيل البيانات المكرّرة. يمكنك تقليل احتمالية تنزيل نفس الجزء من البيانات بشكل متكرر باستخدام التخزين المؤقت. من خلال تخزين بيانات تطبيقك وموارده مؤقتًا، يمكنك إنشاء نسخة محلية من المعلومات التي يحتاج تطبيقك إلى الرجوع إليها. إذا كان تطبيقك يحتاج إلى الوصول إلى المعلومات نفسها عدة مرات خلال فترة زمنية قصيرة، عليك تنزيلها في ذاكرة التخزين المؤقت مرة واحدة فقط.

من المهم تخزين البيانات مؤقتًا بأكبر قدر ممكن لتقليل إجمالي كمية البيانات التي يتم تنزيلها. يجب دائمًا تخزين الموارد الثابتة مؤقتًا، بما في ذلك عمليات التنزيل عند الطلب، مثل الصور بالحجم الكامل، لأطول فترة ممكنة. يجب تخزين الموارد عند الطلب بشكل منفصل لتتمكّن من محو ذاكرة التخزين المؤقت عند الطلب بانتظام لإدارة حجمها.

لضمان عدم عرض تطبيقك لبيانات قديمة بسبب التخزين المؤقت، استخدِم رموز حالة HTTP والعناوين المناسبة، مثل ETag و Last-Modified. يتيح لك ذلك تحديد الوقت الذي يجب فيه إعادة تحميل المحتوى المرتبط. على سبيل المثال:

// url represents the website containing the content to place into the cache.
val conn: HttpsURLConnection = url.openConnection() as HttpsURLConnection
val currentTime: Long = System.currentTimeMillis()
val lastModified: Long = conn.getHeaderFieldDate("Last-Modified", currentTime)

// lastUpdateTime represents when the cache was last updated.
if (lastModified < lastUpdateTime) {
    // Skip update.
} else {
    // Parse update.
    lastUpdateTime = lastModified
}

يمكنك ضبط بعض مكتبات الشبكات لتراعي رموز الحالة والعناوين هذه تلقائيًا. عند استخدام OkHttp مثلاً، سيؤدي ضبط دليل ذاكرة التخزين المؤقت وحجمها للعميل إلى تمكين المكتبة من استخدام التخزين المؤقت لبروتوكول HTTP، كما هو موضّح في عينة التعليمات البرمجية التالية:

val cacheDir = context.getCacheDir()
val cacheSize = 10L * 1024L * 1024L // 10 MiB
val client: OkHttpClient = OkHttpClient.Builder()
    .cache(Cache(cacheDir, cacheSize))
    .build()

بعد ضبط ذاكرة التخزين المؤقت، يمكنك عرض طلبات HTTP المخزّنة مؤقتًا بالكامل مباشرةً من مساحة التخزين المحلية، ما يلغي الحاجة إلى فتح اتصال بالشبكة. يمكن للردود المخزّنة مؤقتًا بشكل مشروط التحقّق من حداثتها من الخادم، ما يقلل من تكلفة معدل نقل البيانات المرتبطة بعملية التنزيل. ويتم تخزين الردود غير المخزّنة مؤقتًا في ذاكرة التخزين المؤقت للردود من أجل الطلبات المستقبلية.

يمكنك تخزين البيانات غير الحسّاسة مؤقتًا في دليل ذاكرة التخزين المؤقت الخارجية غير المُدارة باستخدام Context.getExternalCacheDir(). بدلاً من ذلك، يمكنك تخزين البيانات مؤقتًا في ذاكرة التخزين المؤقت المُدارة والآمنة للتطبيق باستخدام Context.getCacheDir(). يُرجى العِلم أنّه قد يتم محو ذاكرة التخزين المؤقت الداخلية هذه عندما تكون مساحة التخزين المتاحة في النظام منخفضة.

استخدام مستودع

للحصول على نهج أكثر تطورًا للتخزين المؤقت، ضع في اعتبارك نمط تصميم المستودع. يتضمن ذلك إنشاء فئة مخصّصة، تُعرف باسم المستودع، والتي توفّر تجريدًا لواجهة برمجة التطبيقات على بعض البيانات أو الموارد المحدّدة. قد يجلب المستودع بياناته في البداية من مصادر مختلفة، مثل خدمة ويب عن بُعد، ولكنه يوفّر للمتصلين نسخة مخزّنة مؤقتًا من البيانات في المكالمات اللاحقة. تتيح لك هذه الطبقة من التوجيه غير المباشر توفير استراتيجية تخزين مؤقت فعّالة خاصة بتطبيقك. لمزيد من المعلومات حول استخدام نمط المستودع في تطبيقك، يُرجى الاطّلاع على دليل بنية التطبيق.