
Context הוא אובייקט שמספק שירותים שונים באפליקציה, וכשאנחנו מחוץ ל-activity לפעמים אין לנו אותו בהישג יד. ההרצאה מראה מתי נכון להשתמש ב-Context של ה-activity, ואיך להשיג Context ברמת האפליקציה כדי לא להעביר את ה-this בין מחלקות.this, כי Context היא מחלקת בסיס שלו. זה גם הנכון כשמדובר בדברים שקשורים חזק לממשק המשתמש. דוגמה: טוסט עם this בתוך אירוע של לחצן.drawable יש עשר תמונות, וכל לחיצה על לחצן אמורה לבחור אחת אקראית ולהציב אותה כרקע. כל תמונות הרקע התחילו במילה background.getRandomImageId משיגה getResources() ו-getPackageName(), וקוראת ל-R.drawable.class.getDeclaredFields() שמחזיר את כל השדות של המחלקה. זהו נושא שנקרא Reflection. אחר כך מגרילים אינדקס עם Random.nextInt(length), לוקחים את שם השדה עם getName(), ואם השם מתחיל ב-background מחזירים resources.getIdentifier(name, "drawable", packageName). מציבים את התוצאה עם setBackgroundResource.ImageManager כפונקציה public static.getResources ו-getPackageName. פתרון אחד הוא להעביר Context כפרמטר ולהשתמש בו, וזה עובד, אבל מכריח להעביר את ה-this לכל מיני מקומות.MyApp: יוצרים מחלקה שיורשת מ-Application.Context, שמאותחל באירוע onCreate שדורסים, עם getApplicationContext().getContext מחזירה אותו.application מגדירים android:name=".MyApp". הנקודה מציינת את החבילה הראשית של האפליקציה.MyApp.getContext().getResources() מכל מקום, בלי קשר ל-activity ובלי להעביר את this.getApplicationContext.this בכל מקום.הטקסט המלא של הדקות הראשונות בהרצאה «Application Context» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
באחד הסרטונים הקודמים דיברנו על אובייקט מעניין שנקרא קונטקסט ואמרנו שקונטקסט בעצם זה איזשהו אובייקט ששייך לאקטיביטי שמכיל כל מיני שירותים שיכול להיות שאנחנו צריכים להשתמש בהם בכל מיני מקומות באפליקציה.
בסרטון הזה אנחנו הולכים לראות איך אנחנו יכולים להשתמש עם האובייקט הזה גם אם יש לנו אותו בתוך אקטיביטי וגם אם אין לנו אותו במקום אחר שהוא לא האקטיביטי. וכמובן מתי להשתמש בצורה כזאת ומתי להשתמש בו בצורה כזאת.
הדבר הראשון שאנחנו הולכים לראות זה את השימוש הסטנדרטי כאשר אנחנו נמצאים באקטיביטי ואנחנו רוצים את הקונטקסט הזה.
אז הנה יש לנו פה לחצן וכתוב עליו use instance activity context. יש לנו כאן את האירוע שלו ואחת הדוגמאות שעשינו איתו זה פשוט היה להציג טוסט.
כאשר אנחנו רוצים להציג טוסט, אנחנו רואים שהטוסט עצמו מחייב אותנו לשלוח לו את אובייקט הקונטקסט. קונטקסט קיים באקטיביטי, אנחנו אקטיביטי, ולכן אין לנו שום בעיה פשוט לרשום this, כאשר ראינו שהקונטקסט זה מחלקת בסיס של האקטיביטי, ואז כמובן להמשיך ולתת את שאר הפרמטרים של הטוסט.
בואו ניתן פה Hello All, מגדיר שאנחנו רוצים להציג טוסט בזמן שהוא length, והנה יש לנו פה שימוש בקונטקסט של האקטיביטי מתוך האקטיביטי.
בואו נריץ את האפליקציה, הנה התוכנית רצה, בואו נלחץ על הלחצן, וכמובן שאנחנו רואים את הטוסט והכל מוצג כמו שצריך.
והשאלה היא מה בעצם קרה כאן או מתי אנחנו משתמשים בקונטקסט כשהוא שייך לאקטיביטי. אז דבר ראשון אם אני נמצא בתוך אקטיביטי שזה בדיוק מה שקורה כאן אני בתוך מחלקת אקטיביטי, ואני צריך קונטקסט, הכי קל בעולם, אין לי שום בעיה.
הנה הדיס, בבקשה, זה קונטקסט. מקרה נוסף זה שאם אנחנו מתעסקים עם משהו ששייך לאקטיביטי, לדוגמה, אנחנו רוצים להציג משהו שקשור לאקטיביטי או לממשק המשתמש באופן חזק בהקשר האקטיביטי, אז במקרה כזה נכון שהקונטקסט יגיע מהאקטיביטי.
יש מקרים אחרים שהם לא שייכים כקשר חזק מאוד לאקטיביטי ועדיין אנחנו צריכים קונטקסט. אנחנו יכולים לראות את המקרים האלה לדוגמה בגישה למסד הנתונים הפנימי של המכשיר בהמשך כמובן אנחנו נראה איך עושים את זה ובמקרה כזה לדוגמה אנחנו כן צריכים קונטקסט וזה לא משהו שהוא חייב להיות קשור לממשק המשתמש ולאקטיביטי ויש
עוד המון דוגמאות אחרות כשאנחנו צריכים את הקונטקסט אנחנו לא נמצאים באקטיביטי והשאלה מאיפה להשיג אותו. אז בואו נראה דוגמה לביצוע דבר כזה. בואו ניקח את הלחצן, נשכפל אותו ונשאיר את זה כרגע בצורה כזאת.
נרשום פה בוא נניח time שיהיה פה משהו קצת אחר. ניגש וניצור לעצמנו איזשהו אירוע שבו אני רוצה לכתוב קוד אחר שמבצע פעולה עם קונטקסט ובגלל שאנחנו כרגע נמצאים באקטיביטי אז עדיין נשתמש בקונטקסט של האקטיביטי.
ומה שאני רוצה לעשות, אני רוצה להציג על האקטיביטי בלחצן הזה איזושהי תמונה שקיימת בתוך תיקיית דרואובול, אבל בתיקיית דרואובול הכנסתי 10 תמונות שונות ומה שאני רוצה לעשות זה להגריל לתמונה רנדומלית כל פעם שלוחצים על הלחצן ולהציג את התמונה הזאת על האקטיביטי.
לצורך כך, בואו נבנה פה בתוך ה-activity איזושהי פונקציה, נגדיר אותה כ-private int get random image ID, מפני שאנחנו יודעים שכל תמונה מיוצגת על ידי איזשהו ID, ואני רוצה לקבל את ה-ID של תמונה רנדומלית.
בואו נכתוב את הקטע קוד הזה, והקטע קוד הזה הוא מאוד פשוט, resources, כי אני רוצה להגיע ל-resources, אז הנה יש לנו פה אובייקט resources, יש לנו פונקציה שנקראת getResources לאחר מכן אנחנו צריכים את ה-packageName את השם של ה-package של האפליקציה יש לנו פונקציה שנקראת getPackageName תכף אנחנו נראה למה אנחנו
צריכים את ה-packageName עכשיו אנחנו רוצים אובייקט רנדום שיצליח להגריל לנו מספר רנדומלי הדבר הבא שאנחנו רוצים לעשות זה לייצר משהו שנקרא field אנחנו רוצים מערך כזה, field זה איזשהו אובייקט שמתאר data member של מחלקה, field של מחלקה.
בואו נראה רק שהוא רשם לנו פה את ה-package הנכון, נראה ככה ואנחנו רוצים לייצר בעצם את כל התמונות האלה כ-fields של מחלקת ה-drawable.
כאשר ראינו את עולם ה-resources, ראינו בעצם שישנה את המחלקה r שבתוכה יש מחלקות סטטיות בואו נכתוב אותה כאן רגע וכל מחלקה כזאתי זה בעצם מחלקה שמתארת את התיקייה יש לנו פה את הדרובל ואז בעצם אנחנו יודעים שיש מחלקה שנקראת r בתוכה יש מחלקה שנקראת דרובל ובתוכה יש את כל הרכיבים לדוגמה את ה-background
black hive ובלו סנופלק וכל התמונות שאנחנו רואים כאן אבל כל תמונה כזאת מיוצגת על ידי איזשהו שדה בתוך המחלקה הזאת אז אנחנו רוצים את המערך הזה של כל השדות וכל הסיפור של המערך הזה שפשוט מתאר את כל השדות בואו נקרא לו drawable items איך אנחנו משיגים את זה r.drawable.class מתארת לנו מידע לגבי המחלקה הזאת ופונקציה
שנקראת get והנה יש לנו את המערך שמתאר את המשתנים האלה שנוצרו בתוך המחלקה r בתוך המחלקה durable בעצם הנושא הזה נקרא reflection זה נושא ידוע בג'אווה שמאפשר לנו לגשת למחלקה ולהוציא ממנה מידע כל מה שאנחנו רוצים לעשות אנחנו רוצים איזושהי לולאה אפילו שלא תסתיים עד שהיא לא מוצאת לנו איזושהי תמונה מתאימה שלנו אז אנחנו רוצים קודם
כל לייצר רנדום אינדקס, ניקח את ה-RMD נקסט אינט ונקסט אינט יכולה לקבל כמה אנחנו רוצים. בואו ניקח את המערך length כאן יש לנו עכשיו פונקציה רנדומלית שתביא לנו מספר רנדומלי בין 0 ל-length כולל 0 לא כולל ה-length ואז זה בדיוק מאפשר לנו להשיג אינדקס שאנחנו אנחנו יכולים אחר כך להביא פריט במערך הזה.
כעת מה שאנחנו רוצים לעשות זה random index name אנחנו רוצים איזה שהוא שם של תמונה רנדומלית drawable items במיקום ה-random index שמצאנו ולהגיע לפונקציה שנקראת get name הפונקציה get name תביא לנו את השם של השדה הזה כלומר השם background.blackhive לדוגמה, בלי הנקודה jpeg
ובדיוק כמו שהיינו רושמים r.dorable.background.blackhive ממש את השם עצמו, השם background.blackhive לאחר מכן אנחנו רוצים לבדוק האם random image name הזה מתחיל ב-background כי יכול להיות לנו שיש לנו פה כל מיני תמונות אחרות בתוך ה-dorable
שאנחנו לא רוצים אותם בתוך background. זאת הסיבה שכל אחת מהתמונות שאני רוצה שהיא תשמש בתור background של האקטיביטי, התחלתי אותה במילה background, בכדי לבצע הבדלה בין התמונות האחרות שיכולות להיות לנו.
אז אם בעצם אתה מתחיל ב-background, מה שאנחנו רוצים לעשות זה פשוט להחזיר resources.getIdentifier, זה בעצם פונקציה שאומרת לנו איזה פריט אתם רוצים שאני אחזיר לכם, זה יהיה random index name האמת שזה קודם כל צריך להיות שווה כאן והתכוונתי ל-image name זה השם של התמונה עצמה random image name לאחר מכן אנחנו רוצים להגיד לו מאיזה תיקייה אנחנו רוצים את זה זה יהיה drawable
ודבר נוסף שהוא מבקש מאיתנו זה את ה-package name בכדי לדעת באיזה פאקג' זה מוגדר כל הסיפור הזה. אז יש לנו פה את כל מה שאנחנו צריכים, יש לנו את השם של התמונה בלי הנקודה jpeg, יש לנו מאיזה תיקייה, drawable, יש לנו את ה-package name שהשגנו, כל זה נמצא ב-resources,
הנה יש לנו את ה-resources, אנחנו מחזירים את זה, בואו ניפטר רגע מהרווחים המיותרים האלה, והנה יש לנו פונקציה שנקראת getRandomImageID שהיא אוטומטית, הולכת לתיקיית הדרובל ומגרילה כאן איזושהי תמונה ומחזירה את ה-ID שלה ולא מעניין אותי ולא משנה לי אם מחר או
בעוד חודש אנחנו נוסיף פה עוד תמונות שמתחילות ב-Background. הפונקציה הזאת עובדת, עושה את העבודה ופשוט תביא לנו תמונה רנדומלית. כל מה שאנחנו רוצים לעשות זה לגשת ל-Activity, הנה יש לנו אותו פה למעלה וב-Activity להגדיר set background resource ולקרוא לפונקציה get random image ID יש לנו פה את כל הקוד
מוכן בואו נריץ את האפליקציה הנה היא רצה לה לחצן ראשון מציג את הטקסט כמו שצריך ולחצן שני פשוט מגריל תמונה מהתמונות שיש כל פעם שאני מבצע לחיצה אנחנו רואים איזושהי תמונה שהיא מוגרלת ומוצבת על האקטיביטי הנה יש לנו פה תמונות שונות חלק מהתמונות מוגרלות שוב פעם כמה פעמים כי יש לנו סך הכל 10 תמונות.
זאת אומרת עד כאן הכל עובד כמו שצריך אבל הנה הנקודה, איפה כתבנו את הפונקציה הזאת? את הפונקציה הזאת כתבנו בתוך ה-activity. האם באמת בפרויקט אמיתי בתעשייה אני רוצה שהפונקציה הזאת תיכתב בתוך ה-activity?
התשובה היא לא, אני לא רוצה ברוב המקרים שפונקציה כזאת תיכתב בתוך ה-activity. למה?
דבר ראשון היא לא בדיוק קשורה לפעילות של האקטיביטי היא מחזירה לי איזה שהוא רנדום אימג' איידי שיכול לשמש אותי לכל מיני דברים אחרים.
דבר שני זה פעילות לוגית היא לא הכי קשורה ל-UI לממשק המשתמש אני רוצה להוציא פעילויות לוגיות למחלקות אחרות. דבר שלישי אני רוצה לנקות כמה שיותר את האקטיביטי אני לא רוצה שיהיה לי פה כל מיני קודים לוגיים.
דבר רביעי אולי בעוד אקטיביטיז אני ארצה את הפעילות הזאת, מה אני אעשה? קופי פלייסט עכשיו של הפונקציה וידביק אותה בכל מיני אקטיביטיז אחרים? לכן הדבר הנכון לעשות בפרויקט אמיתי זה לקחת את הפונקציה הזאת ופשוט להוציא אותה לאיזושהי מחלקה חיצונית שזה יהיה התפקיד שלה, לנהל את כל הפעילות של התמונות הרנדומניות.
אז בואו נעשה את זה. בואו ניגש לתיקייה של האתר, נוסיף מחלקה חדשה, נקרא לה image manager, היא מנהלת לי את התמונות, נחזור בחזרה, נגזור את כל הפונקציה הזאת, נדביק אותה בתוך המחלקה עם כל הפאקג' הזה שצריך, נגדיר אותה כפאבליק וסטטיק כי אנחנו רוצים
לקרוא לה בלי ליצור אובייקט מהמחלקה אימג'. הרי הגיוני שאם אנחנו לא משתמשים במשתני מחלקה, אז הגיוני שהפונקציה שלנו תהיה פונקציה סטטית ברוב המקרים, כן?
במקרה הזה אני רוצה שהיא תהיה סטטית גם בכדי שיהיה לי ממש נוח לקרוא לה. אם אני חוזר בחזרה אז כמובן הפונקציה הזאת כבר לא נמצאת אצלי באקטיביטי. בשביל לקרוא לה אני צריך להגדיר את השם image-manager נקודה והנה יש לנו פה את הפונקציה getRandomImageID זאת אומרת אין שום בעיה מתוך האקטיביטי להפעיל את הפונקציה הזאתי זה ממש דבר נוח