AndroidAnnotations: הזרקת התלויות מבוססת שמות
אחרי שעסקתי בספריית הזרקת התלויות האולטימטיבית, הפעם ארחיב על ספריה נוספת ומעניינת בתחום ● וגם: איך מממשים תקשורת בין רכיבית בצורה פשוטה?
הטור הקודם עסק בשאלות כיצד בוחרים ספריית פיתוח ומהן התכונות החשובות שדרושות לספריה כדי שניתן יהיה לפתח באמצעותה על הצד הטוב ביותר. חלקו השני עסק ב-ButterKnife – ספריית הזרקת התלויות האולטימטיבית. אלא שהיא לא היחידה בתחום.
ספריה נוספת בתחום ספריות הזרקת התלויות היא AndroidAnnotations. היא משתמשת בגישה שונה מעט שמניסיוני – קל מאוד להתרגל אליה. כאן, מחלקות מיוצרות בזמן קומפילציה (Automatically generated classes), שיורשות מה-Activity classes שאותם כתב המפתח ושבתוכן מתבצעת הזרקת התלויות.
גישה זו מאפשרת את הקסם שנקרא הזרקת תלויות מבוססת שם (Name based injection), שבו ההזרקה מתבצעת ללא צורך בתיוג (Annotation), כל עוד שם השדה של ה-View בקוד הג'אווה (Java) זהה לשמו בקובץ ה-XML layout.
צורת מימוש זו הופכת את AndroidAnnotation למהירה מאוד בזמן ריצה. למעשה, זוהי כנראה ספריית ההזרקה המהירה ביותר שקיימת כיום לאנדרואיד (Android). הסיבה לכך היא שה-Automatically generated classes שאותם היא מייצרת משתמשים בקוד זהה לזה שבמימוש ידני של קישור Java-XML – ולכן הוא מהיר באותה המידה.
יכולות ההזרקה של AndroidAnnotation לא נעצרות כאן. באפשרות המפתחים לבצע הזרקה של עוד לא מעט משתנים נפוצים בקוד אנדרואיד. ראו דוגמה:הפונקציה updateUI() דורשת הסבר נוסף: משימה נפוצה עבור אפליקציית אנדרואיד מרובת נימים (Multi threads) היא הפעלה, מתוך נימי רקע (Background/worker threads), של לוגיקה על הנים הראשי (Main/UI thread), שרק ממנו ניתן לעדכן רכיבי ממשק משתמש במערכת. משימה זו, על אף שאינה מורכבת במיוחד, דורשת כתיבת קוד מסורבל, שפוגע בקריאות ופשטות המערכת. משהו כזה:
במקום זאת, שימוש ב-AndroidAnnotation יאפשר לתייג את הפונקציה בתג UIThread@ ולהבטיח בכך שהיא תורץ אך ורק על הנים הראשי, ללא קשר לנים שממנו הופעלה.
שימו לב שיכולת זו מתייחסת רק למחלקות של רכיבי אנדרואיד סטנדרטיים (Activities, Services וכדומה). אם תרצו לבצע תיוג למחלקות שאינן רכיבים סטנדרטיים (כמו controllers, observers או models), תידרשו להגדיר אותן כמחלקות מסוג EBean, כפי שנראה כאן:
EventBus – הדרך הפשוטה למימוש תקשורת בין רכיבית
הספרייה EventBus פותרת בעיה שהעסיקה מפתחי אנדרואיד במשך זמן רב ומפשטת אותה עד מאוד: היא מאפשרת ביצוע תקשורת בין רכיבית בשימוש במודל Pub/sub פשוט ונטול "תופעות לוואי" בין שני חלקים – כל שני חלקים – במערכת.
שימוש ב- EventBus מביא לקוד יציב וברור יותר, שכן הוא מאלץ את המפתח להקטין את התלויות שבין רכיבי המערכת ובכך לייצר מערכת מוחלשת תלויות (Loosely coupled). בניסוח פשוט יותר – רכיב א׳ של המערכת לא צריך להכיר את הרכיבים ב׳ ו-ג׳ על מנת להעביר להם נתונים ופקודות לביצוע.
כדוגמת שימוש פרקטית ניתן לחשוב על Background polling service שדוגם את מצב המערכת או אולי שרת מרוחק. בשימוש ב-EventBus KT צריך יותר להיות מודע ל-UI fragments של המערכת על מנת להזינם במידע הנדרש לצורך הצגת השינויים.
שימוש בסיסי ב-EventBus מתחלק לארבעה חלקים:
ראשית, צרו מחלקות אירוע (Event classes). אני בדרך כלל משתמש כאן באובייקטי מידע בסיסיים (Java POJOs), אף על פי שאין בכך חובה.
שנית, צרו במחלקה מתודות לטיפול באירועים. הכוונה היא לכל מחלקה שאתם מעוניינים לרשום בה אירועים אלה.
חשוב לשים לב למודל הנימים (Thread-model) של ה-Handler-ים שהגדרתם באותו הרגע כברירת מחדל. כל מתודות ה-Handler-ים מורצות על גבי Thread pool המוקצה ומתוחזק על ידי EventBus עצמה. במידה שאתם נדרשים להריץ את ה-Handler על הנים הראשי (Main thread), יש לשנות את תיוג המתודה כך:
שימו לב שלא לבצע שימוש יתר בתכונה זו. אסור שפעולות הדורשות זמן הרצה ארוך יופעלו על הנים הראשי, ואפילו כאשר מדובר בפעולות מהירות – היו זהירים. הצפת הנים הראשי היא הדרך הבטוחה ביותר להפוך את האפליקציה שלכם לאיטית, קופצנית ובאופן כללי פחות מהנה עבור המשתמשים.
שלישית, נהלו את מחזור חיי ההרשמה (Registration Lifecyle) ל-EventBus של מחלקת המנויים שלכם – הווה אומר, מתי הוא מתחבר ומתי הוא מתנתק מהערוץ? זרימת הרשמה סבירה עבור פעילות יכולה להיות:
הרשום לעיל הוא דוגמה בלבד. באפשרותכם לבצע הרשמה (או ביטול הרשמה) מכל מקום בו תבחרו.
לבסוף, שגרו את האירוע:
יש עוד הרבה ללמוד אודות השימוש ב-EventBus: אירועים מסוג Multicast, שימוש באירועים דביקים (Sticky events), תהליכי העברה, סדרי עדיפויות ועוד. אולם, הדוגמאות שלעיל יספיקו לכם בכדי להתחיל להשתמש בטכנולוגיה פשוטה אך עוצמתית זו.
בשבוע הבא: על OkHttp – הגרסה המשופרת ל-HttpClient של אנדרואיד, ועל פיקאסו (Picasso) – ספריה שגם גוגל (Google) משתמשת בה, ומסיבות טובות.
הכותב הינו מפתח אנדרואיד עצמאי ומנכ"ל Mobile edge software solutions.
כתבה מעולה. כמו כולן בסדרה.
לשאלתך גיא - Event Bus עובד בתחומי ה-process בלבד. ואולם קיים מעקף פשוט לבעיה זו - תפוס את הדיווחים מה remote process ב- broadcast receiver שמוגדר ב process הראשי ומתוכו תבצע post לשאר רכיבי ה-process
Very insightful!
כתבה מעולה. אגב לגבי ה EVENT BUS האם הוא יודע להאזין CROSS PROCESS לדוגמא בין SERVICE (ב PROCESS אחר) ל ACTIVITY ?