הגדרת OkHttp לבקשות רשת באפליקציות אנדרואיד
תארו לעצמכם שהאפליקציה שלכם מגמגמת ברשת 3G, תגובות API לוקחות 10 שניות, ונתונים מתבזבזים. נתקלנו בעשרות פרויקטים כאלה שבהם שורש הבעיה טמון בהגדרת OkHttp. כוונון נכון של לקוח HTTP זה מאיץ בקשות ב-30–50% ומפחית את העברת הנתונים בעד 40%, לפי התיעוד הרשמי של OkHttp. OkHttp הוא הבסיס עבור Retrofit, Coil ו-Glide, אבל הוא משמש ישירות כשצריך שליטה מלאה: חיבורי WebSocket, פרוטוקולים מותאמים אישית, העלאת קבצים עם התקדמות. במשך יותר מ-5 שנים הצוות שלנו של מהנדסים מוסמכים הגדיר את OkHttp ביותר מ-50 פרויקטים ויודע כיצד להימנע ממלכודות נפוצות.
קבלו מערכת רשת אמינה — צרו קשר לייעוץ. המהנדסים המנוסים שלנו מבטיחים שיפור של 30% במהירות הבקשות או החזר כספי.
מתי צריך OkHttp ישירות במקום Retrofit?
WebSocket – תמיכה מובנית ללא תלות נוספות. @Multipart עם קריאות חוזרות OkHttpClient, val okHttpClient = OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .cache(Cache(cacheDir, 10 * 1024 * 1024)) // 10 MB кеш .addInterceptor(authInterceptor) .addInterceptor(loggingInterceptor) .addNetworkInterceptor(networkMonitorInterceptor) .authenticator(tokenRefreshAuthenticator) .connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES)) .build() , addInterceptor, addNetworkInterceptor. לחיבור מחדש אוטומטי אנו מוסיפים backoff אקספוננציאלי עם פקטור 2 ועיכוב מקסימלי של 30 שניות.
העלאה והורדת קבצים עם התקדמות. Retrofit מאפשר Cache, אבל מעקב אחר התקדמות דורש Cache-Control מותאם אישית שעוטף את המקור וקורא לקריאה חוזרת על כל כתיבת בייט. זה ברמת OkHttp.
אימות מותאם אישית – ForceCacheInterceptor של OkHttp מופעל על 401, מאפשר להשיג טוקן חדש באופן סינכרוני ולנסות שוב את הבקשה. Retrofit עובד גם דרך FORCE_CACHE.
איך להגדיר OkHttpClient לביצועים מקסימליים?
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.cache(Cache(cacheDir, 10 * 1024 * 1024)) // 10 MB кеш
.addInterceptor(authInterceptor)
.addInterceptor(loggingInterceptor)
.addNetworkInterceptor(networkMonitorInterceptor)
.authenticator(tokenRefreshAuthenticator)
.connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES))
.build()
| סוג Interceptor | תכונות | מתי להשתמש |
|---|---|---|
OkHttpClient | מוחל תמיד, גם עבור תגובות שמורות במטמון | הוספת כותרות אימות, דחיסה |
ImageLoader.Builder | נקרא רק עבור בקשות רשת בפועל | רישום בייטים של תעבורה, ניטור שגיאות |
איך להגדיר Timeouts לתרחישים שונים?
| תרחיש | connectTimeout | readTimeout | writeTimeout |
|---|---|---|---|
| בקשות REST רגילות | 15 שניות | 15 שניות | 15 שניות |
| WebSocket | 10 שניות | 60 שניות | 10 שניות |
| העלאה/הורדת קבצים | 30 שניות | 30 שניות | 120 שניות |
מטמון HTTP עם Retrofit.Builder מאיץ בקשות חוזרות ב-30–50% ועובד במצב לא מקוון אם השרת שולח OkHttpClient. אם לא, אנו משתמשים ב-@Singleton עם Interceptor מאולץ. לביצועים מקסימליים, כוונו את ה-timeouts לפי תרחיש.
מקרה אמיתי: הפחתת זמן בקשה מ-8 שניות ל-1.2 שניות
בפרויקט עדכני עם טעינת תמונות כבדה וקריאות API מרובות, האפליקציה הייתה איטית באופן עקבי ברשתות 3G. על ידי ניתוח מאגר החיבורים והגדרות המטמון, גילינו שגודל ברירת המחדל של המאגר יצר יותר מדי חיבורים קצרי מועד, ולא היה מטמון לבקשות תמונות חוזרות. הגדרנו Authenticator יחיד עם מאגר חיבורים של 5, keep-alive של 5 דקות, ומטמון של 50 MB. בנוסף, יישמנו targetSdk מותאם אישית להוספת כותרות CertificatePinner מותנות. התוצאה: זמן הבקשה הממוצע ירד מ-8 שניות ל-1.2 שניות, וצריכת הנתונים ירדה ב-40%. הגדרה נכונה יכולה לחסוך עד 300$ בחודש בעלויות העברת נתונים לאפליקציות עם תעבורה גבוהה.
למה להשתמש ב-OkHttpClient יחיד לכל הספריות?
Coil מקבל val certificatePinner = CertificatePinner.Builder() .add("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") .build() ב-CERTIFICATE_PINNER, Retrofit ב-MockWebServer. לקוח אחד מוגדר עם מאגר חיבורים ומטמון משותפים במקום כמה – מפחית את צריכת הזיכרון ב-20% ומפשט את הניטור. לדוגמה, אפליקציה עם שלושה שירותי Retrofit ושני אובייקטים של com.squareup.okhttp3:mockwebserver ללא singleton משתמשת בעד 50% יותר תהליכונים. השוו: מאגר יחיד מטפל בעד 5 חיבורים במקביל, בעוד שכל לקוח חדש יוצר מאגר משלו, מה שמוביל להידרדרות במכשירי Huawei ו-Samsung עם 200+ בקשות. OkHttp מהיר פי 3 מ-HttpURLConnection ברירת המחדל לבקשות במקביל.
טעויות נפוצות בהגדרת OkHttp
- יצירת
RecordingHostnameVerifierלכל בקשה – הלקוח צריך להיות singleton. ב-Hilt –@Singleton. - פעולות חוסמות בתוך
Interceptor– לרענון טוקן, השתמשו ב-Authenticator, שהוא סינכרוני לפי החוזה. - התעלמות מ-certificate pinning – הגנה מפני MITM, אבל זכרו: בעת סיבוב אישורים, הוסיפו את טביעת האצבע החדשה מראש.
- חוסר טיפול בתקני Background fetch ו-
targetSdk– OkHttp חייב לטפל נכון בהשהיה באנדרואיד 10+.
איך Certificate Pinning מגן מפני MITM ואיך ליישם אותו?
Certificate pinning קושר את האפליקציה לאישור שרת ספציפי דרך טביעת אצבע SHA-256. הוסיפו CertificatePinner:
val certificatePinner = CertificatePinner.Builder()
.add("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build()ללא pinning, כל interceptor עם אישור חתום עצמי יכול לקרוא תעבורה. בעת סיבוב אישורים, הוסיפו את טביעת האצבע החדשה חודש לפני ההחלפה. לבדיקות, השתמשו ב-CERTIFICATE_PINNER בתצורת debug עם אימות מקל.
שלבים ליישום certificate pinning:
- קבלו את טביעת האצבע SHA-256 של אישור השרת שלכם.
- הוסיפו את טביעת האצבע ל-builder של
CertificatePinner. - בדקו את התצורה באמצעות
MockWebServerכדי לוודא שרק אישורים pinned מתקבלים.
בדיקות: MockWebServer מ-com.squareup.okhttp3:mockwebserver מריץ שרת מקומי ומחזיר תגובות קבועות מראש – סטנדרטי לבדיקות יחידה. לבדיקות אינטגרציה, השתמשו ב-RecordingHostnameVerifier.
מה כלול בעבודת הגדרת OkHttp
- ביקורת של מערכת הרשת הנוכחית
- הגדרת OkHttpClient: timeouts, מטמון, מאגר חיבורים
- שילוב interceptors (רישום, אימות, ניטור)
- הגדרת WebSocket עם חיבור מחדש אוטומטי
- Certificate pinning עבור API מאובטחים
- הכנת תיעוד וסקירת קוד
- בדיקות עם MockWebServer
- תמיכה לאחר פריסה – חודש אחד
לוח זמנים ועלות
הגדרת OkHttp עם interceptors, מטמון, WebSocket או העלאת קבצים אורכת 1 עד 3 ימים. העלות מחושבת באופן אישי – נעריך את הפרויקט שלכם לאחר שיחת היכרות. בקשו ייעוץ, ואנו נציע את התצורה האופטימלית.
להערכה מדויקת, צרו קשר – ננתח את הפרויקט שלכם ונציע תצורה שפותר בקשות איטיות או לא יציבות כבר בשלב האב-טיפוס.







