PracticU

Application Context

בלי כתוביותעם כתוביות
PracticU › קורס פיתוח אפליקציות - לאנדרואיד - Android - ב-JAVA › Application Context
מילון מושגים:
Activity - ב-Android, רכיב שמייצג מסך יחיד של האפליקציה שאיתו המשתמש מתקשר.
אירוע - התרחשות שהמערכת מזהה ויכולה להגיב לה, כמו לחיצת עכבר, הקשה או סיום פעולה.
אינדקס - מבנה במסד נתונים שמאיץ חיפוש ושליפה. גם מספר המציין מיקום של איבר במערך.
פרמטר - ערך שמועבר לפונקציה או לפקודה כקלט, ומשפיע על אופן פעולתן ועל התוצאה שהן מחזירות.
תגית - סימון בקוד, למשל ב-HTML, שתוחם רכיב ומגדיר את תפקידו או תכונותיו. גם תווית לסימון וקיטלוג פריטים.
Android - מערכת הפעלה מבוססת Linux לטלפונים ולמכשירים ניידים, שפותחה על ידי גוגל.
חבילה - אוסף ארוז של קוד, ספריות או קבצים המופץ כיחידה אחת ומותקן בעזרת מנהל חבילות.
אחסון - שמירת נתונים באופן קבוע על התקנים כמו דיסקים או שירותי ענן, כך שיישמרו גם לאחר כיבוי.

Application Context
Context הוא אובייקט שמספק שירותים שונים באפליקציה, וכשאנחנו מחוץ ל-activity לפעמים אין לנו אותו בהישג יד. ההרצאה מראה מתי נכון להשתמש ב-Context של ה-activity, ואיך להשיג Context ברמת האפליקציה כדי לא להעביר את ה-this בין מחלקות.
מתי Context של activity
כשכותבים בתוך activity אפשר להשתמש ב-this, כי Context היא מחלקת בסיס שלו. זה גם הנכון כשמדובר בדברים שקשורים חזק לממשק המשתמש. דוגמה: טוסט עם this בתוך אירוע של לחצן.
הדוגמה: תמונת רקע אקראית
1. הצורך: ב-drawable יש עשר תמונות, וכל לחיצה על לחצן אמורה לבחור אחת אקראית ולהציב אותה כרקע. כל תמונות הרקע התחילו במילה background.
2. הפונקציה: getRandomImageId משיגה getResources() ו-getPackageName(), וקוראת ל-R.drawable.class.getDeclaredFields() שמחזיר את כל השדות של המחלקה. זהו נושא שנקרא Reflection. אחר כך מגרילים אינדקס עם Random.nextInt(length), לוקחים את שם השדה עם getName(), ואם השם מתחיל ב-background מחזירים resources.getIdentifier(name, "drawable", packageName). מציבים את התוצאה עם setBackgroundResource.
3. מחלקה חיצונית: הפונקציה לא שייכת ל-activity. היא לא קשורה לממשק, היא פעילות לוגית, רוצים activity נקי, ואולי יצטרכו אותה במסכים אחרים. לכן הועברה למחלקה ImageManager כפונקציה public static.
4. הבעיה: בתוך מחלקה אחרת אין getResources ו-getPackageName. פתרון אחד הוא להעביר Context כפרמטר ולהשתמש בו, וזה עובד, אבל מכריח להעביר את ה-this לכל מיני מקומות.
Context ברמת האפליקציה
1. מחלקה MyApp: יוצרים מחלקה שיורשת מ-Application.
2. שמירת הקונטקסט: משתנה סטטי פרטי מסוג Context, שמאותחל באירוע onCreate שדורסים, עם getApplicationContext().
3. פונקציה סטטית: getContext מחזירה אותו.
4. רישום במניפסט: בתגית application מגדירים android:name=".MyApp". הנקודה מציינת את החבילה הראשית של האפליקציה.
5. שימוש: MyApp.getContext().getResources() מכל מקום, בלי קשר ל-activity ובלי להעביר את this.
שימו לב
- אם צריך Context שקשור ממש לממשק של activity, משתמשים ב-activity. אם צריך Context כללי, כמו חיפוש משאבים, גישה לאחסון פנימי (נראה בהמשך) או העברה למחלקה של המערכת, מספיק Context של האפליקציה.
- גם ב-activity עצמו קיימת הפונקציה getApplicationContext.
אחרי ההרצאה אפשר לבחור בין Context של activity ל-Context של האפליקציה, ולהוציא קוד לוגי למחלקות נפרדות בלי להעביר את ה-this בכל מקום.

פרקי ההרצאה: Application Context

  1. 00:00

    Context של האקטיביטי והצגת Toast

  2. 02:33

    מתי צריך Context מחוץ לאקטיביטי

  3. 03:33

    לחצן להצגת תמונה אקראית

  4. 04:46

    גישה ל-Resources ויצירת Random

  5. 05:25

    קריאת תמונות Drawable עם Reflection

  6. 07:40

    בחירת שם תמונה אקראי

  7. 09:38

    קבלת ה-ID עם getIdentifier

  8. 12:17

    העברת הפונקציה למחלקת ImageManager

תמלול ההרצאה: Application Context

הטקסט המלא של הדקות הראשונות בהרצאה «Application Context» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.

  1. 00:02

    באחד הסרטונים הקודמים דיברנו על אובייקט מעניין שנקרא קונטקסט ואמרנו שקונטקסט בעצם זה איזשהו אובייקט ששייך לאקטיביטי שמכיל כל מיני שירותים שיכול להיות שאנחנו צריכים להשתמש בהם בכל מיני מקומות באפליקציה.

  2. 00:20

    בסרטון הזה אנחנו הולכים לראות איך אנחנו יכולים להשתמש עם האובייקט הזה גם אם יש לנו אותו בתוך אקטיביטי וגם אם אין לנו אותו במקום אחר שהוא לא האקטיביטי. וכמובן מתי להשתמש בצורה כזאת ומתי להשתמש בו בצורה כזאת.

  3. 00:39

    הדבר הראשון שאנחנו הולכים לראות זה את השימוש הסטנדרטי כאשר אנחנו נמצאים באקטיביטי ואנחנו רוצים את הקונטקסט הזה.

  4. 00:48

    אז הנה יש לנו פה לחצן וכתוב עליו use instance activity context. יש לנו כאן את האירוע שלו ואחת הדוגמאות שעשינו איתו זה פשוט היה להציג טוסט.

  5. 01:02

    כאשר אנחנו רוצים להציג טוסט, אנחנו רואים שהטוסט עצמו מחייב אותנו לשלוח לו את אובייקט הקונטקסט. קונטקסט קיים באקטיביטי, אנחנו אקטיביטי, ולכן אין לנו שום בעיה פשוט לרשום this, כאשר ראינו שהקונטקסט זה מחלקת בסיס של האקטיביטי, ואז כמובן להמשיך ולתת את שאר הפרמטרים של הטוסט.

  6. 01:30

    בואו ניתן פה Hello All, מגדיר שאנחנו רוצים להציג טוסט בזמן שהוא length, והנה יש לנו פה שימוש בקונטקסט של האקטיביטי מתוך האקטיביטי.

  7. 01:47

    בואו נריץ את האפליקציה, הנה התוכנית רצה, בואו נלחץ על הלחצן, וכמובן שאנחנו רואים את הטוסט והכל מוצג כמו שצריך.

  8. 01:58

    והשאלה היא מה בעצם קרה כאן או מתי אנחנו משתמשים בקונטקסט כשהוא שייך לאקטיביטי. אז דבר ראשון אם אני נמצא בתוך אקטיביטי שזה בדיוק מה שקורה כאן אני בתוך מחלקת אקטיביטי, ואני צריך קונטקסט, הכי קל בעולם, אין לי שום בעיה.

  9. 02:16

    הנה הדיס, בבקשה, זה קונטקסט. מקרה נוסף זה שאם אנחנו מתעסקים עם משהו ששייך לאקטיביטי, לדוגמה, אנחנו רוצים להציג משהו שקשור לאקטיביטי או לממשק המשתמש באופן חזק בהקשר האקטיביטי, אז במקרה כזה נכון שהקונטקסט יגיע מהאקטיביטי.

  10. 02:39

    יש מקרים אחרים שהם לא שייכים כקשר חזק מאוד לאקטיביטי ועדיין אנחנו צריכים קונטקסט. אנחנו יכולים לראות את המקרים האלה לדוגמה בגישה למסד הנתונים הפנימי של המכשיר בהמשך כמובן אנחנו נראה איך עושים את זה ובמקרה כזה לדוגמה אנחנו כן צריכים קונטקסט וזה לא משהו שהוא חייב להיות קשור לממשק המשתמש ולאקטיביטי ויש

  11. 03:00

    עוד המון דוגמאות אחרות כשאנחנו צריכים את הקונטקסט אנחנו לא נמצאים באקטיביטי והשאלה מאיפה להשיג אותו. אז בואו נראה דוגמה לביצוע דבר כזה. בואו ניקח את הלחצן, נשכפל אותו ונשאיר את זה כרגע בצורה כזאת.

  12. 03:28

    נרשום פה בוא נניח time שיהיה פה משהו קצת אחר. ניגש וניצור לעצמנו איזשהו אירוע שבו אני רוצה לכתוב קוד אחר שמבצע פעולה עם קונטקסט ובגלל שאנחנו כרגע נמצאים באקטיביטי אז עדיין נשתמש בקונטקסט של האקטיביטי.

  13. 03:52

    ומה שאני רוצה לעשות, אני רוצה להציג על האקטיביטי בלחצן הזה איזושהי תמונה שקיימת בתוך תיקיית דרואובול, אבל בתיקיית דרואובול הכנסתי 10 תמונות שונות ומה שאני רוצה לעשות זה להגריל לתמונה רנדומלית כל פעם שלוחצים על הלחצן ולהציג את התמונה הזאת על האקטיביטי.

  14. 04:16

    לצורך כך, בואו נבנה פה בתוך ה-activity איזושהי פונקציה, נגדיר אותה כ-private int get random image ID, מפני שאנחנו יודעים שכל תמונה מיוצגת על ידי איזשהו ID, ואני רוצה לקבל את ה-ID של תמונה רנדומלית.

  15. 04:40

    בואו נכתוב את הקטע קוד הזה, והקטע קוד הזה הוא מאוד פשוט, resources, כי אני רוצה להגיע ל-resources, אז הנה יש לנו פה אובייקט resources, יש לנו פונקציה שנקראת getResources לאחר מכן אנחנו צריכים את ה-packageName את השם של ה-package של האפליקציה יש לנו פונקציה שנקראת getPackageName תכף אנחנו נראה למה אנחנו

  16. 05:08

    צריכים את ה-packageName עכשיו אנחנו רוצים אובייקט רנדום שיצליח להגריל לנו מספר רנדומלי הדבר הבא שאנחנו רוצים לעשות זה לייצר משהו שנקרא field אנחנו רוצים מערך כזה, field זה איזשהו אובייקט שמתאר data member של מחלקה, field של מחלקה.

  17. 05:36

    בואו נראה רק שהוא רשם לנו פה את ה-package הנכון, נראה ככה ואנחנו רוצים לייצר בעצם את כל התמונות האלה כ-fields של מחלקת ה-drawable.

  18. 06:00

    כאשר ראינו את עולם ה-resources, ראינו בעצם שישנה את המחלקה r שבתוכה יש מחלקות סטטיות בואו נכתוב אותה כאן רגע וכל מחלקה כזאתי זה בעצם מחלקה שמתארת את התיקייה יש לנו פה את הדרובל ואז בעצם אנחנו יודעים שיש מחלקה שנקראת r בתוכה יש מחלקה שנקראת דרובל ובתוכה יש את כל הרכיבים לדוגמה את ה-background

  19. 06:31

    black hive ובלו סנופלק וכל התמונות שאנחנו רואים כאן אבל כל תמונה כזאת מיוצגת על ידי איזשהו שדה בתוך המחלקה הזאת אז אנחנו רוצים את המערך הזה של כל השדות וכל הסיפור של המערך הזה שפשוט מתאר את כל השדות בואו נקרא לו drawable items איך אנחנו משיגים את זה r.drawable.class מתארת לנו מידע לגבי המחלקה הזאת ופונקציה

  20. 06:42

    שנקראת get והנה יש לנו את המערך שמתאר את המשתנים האלה שנוצרו בתוך המחלקה r בתוך המחלקה durable בעצם הנושא הזה נקרא reflection זה נושא ידוע בג'אווה שמאפשר לנו לגשת למחלקה ולהוציא ממנה מידע כל מה שאנחנו רוצים לעשות אנחנו רוצים איזושהי לולאה אפילו שלא תסתיים עד שהיא לא מוצאת לנו איזושהי תמונה מתאימה שלנו אז אנחנו רוצים קודם

  21. 07:43

    כל לייצר רנדום אינדקס, ניקח את ה-RMD נקסט אינט ונקסט אינט יכולה לקבל כמה אנחנו רוצים. בואו ניקח את המערך length כאן יש לנו עכשיו פונקציה רנדומלית שתביא לנו מספר רנדומלי בין 0 ל-length כולל 0 לא כולל ה-length ואז זה בדיוק מאפשר לנו להשיג אינדקס שאנחנו אנחנו יכולים אחר כך להביא פריט במערך הזה.

  22. 08:16

    כעת מה שאנחנו רוצים לעשות זה random index name אנחנו רוצים איזה שהוא שם של תמונה רנדומלית drawable items במיקום ה-random index שמצאנו ולהגיע לפונקציה שנקראת get name הפונקציה get name תביא לנו את השם של השדה הזה כלומר השם background.blackhive לדוגמה, בלי הנקודה jpeg

  23. 08:51

    ובדיוק כמו שהיינו רושמים r.dorable.background.blackhive ממש את השם עצמו, השם background.blackhive לאחר מכן אנחנו רוצים לבדוק האם random image name הזה מתחיל ב-background כי יכול להיות לנו שיש לנו פה כל מיני תמונות אחרות בתוך ה-dorable

  24. 09:20

    שאנחנו לא רוצים אותם בתוך background. זאת הסיבה שכל אחת מהתמונות שאני רוצה שהיא תשמש בתור background של האקטיביטי, התחלתי אותה במילה background, בכדי לבצע הבדלה בין התמונות האחרות שיכולות להיות לנו.

  25. 09:34

    אז אם בעצם אתה מתחיל ב-background, מה שאנחנו רוצים לעשות זה פשוט להחזיר resources.getIdentifier, זה בעצם פונקציה שאומרת לנו איזה פריט אתם רוצים שאני אחזיר לכם, זה יהיה random index name האמת שזה קודם כל צריך להיות שווה כאן והתכוונתי ל-image name זה השם של התמונה עצמה random image name לאחר מכן אנחנו רוצים להגיד לו מאיזה תיקייה אנחנו רוצים את זה זה יהיה drawable

  26. 10:19

    ודבר נוסף שהוא מבקש מאיתנו זה את ה-package name בכדי לדעת באיזה פאקג' זה מוגדר כל הסיפור הזה. אז יש לנו פה את כל מה שאנחנו צריכים, יש לנו את השם של התמונה בלי הנקודה jpeg, יש לנו מאיזה תיקייה, drawable, יש לנו את ה-package name שהשגנו, כל זה נמצא ב-resources,

  27. 10:42

    הנה יש לנו את ה-resources, אנחנו מחזירים את זה, בואו ניפטר רגע מהרווחים המיותרים האלה, והנה יש לנו פונקציה שנקראת getRandomImageID שהיא אוטומטית, הולכת לתיקיית הדרובל ומגרילה כאן איזושהי תמונה ומחזירה את ה-ID שלה ולא מעניין אותי ולא משנה לי אם מחר או

  28. 11:06

    בעוד חודש אנחנו נוסיף פה עוד תמונות שמתחילות ב-Background. הפונקציה הזאת עובדת, עושה את העבודה ופשוט תביא לנו תמונה רנדומלית. כל מה שאנחנו רוצים לעשות זה לגשת ל-Activity, הנה יש לנו אותו פה למעלה וב-Activity להגדיר set background resource ולקרוא לפונקציה get random image ID יש לנו פה את כל הקוד

  29. 11:37

    מוכן בואו נריץ את האפליקציה הנה היא רצה לה לחצן ראשון מציג את הטקסט כמו שצריך ולחצן שני פשוט מגריל תמונה מהתמונות שיש כל פעם שאני מבצע לחיצה אנחנו רואים איזושהי תמונה שהיא מוגרלת ומוצבת על האקטיביטי הנה יש לנו פה תמונות שונות חלק מהתמונות מוגרלות שוב פעם כמה פעמים כי יש לנו סך הכל 10 תמונות.

  30. 12:08

    זאת אומרת עד כאן הכל עובד כמו שצריך אבל הנה הנקודה, איפה כתבנו את הפונקציה הזאת? את הפונקציה הזאת כתבנו בתוך ה-activity. האם באמת בפרויקט אמיתי בתעשייה אני רוצה שהפונקציה הזאת תיכתב בתוך ה-activity?

  31. 12:32

    התשובה היא לא, אני לא רוצה ברוב המקרים שפונקציה כזאת תיכתב בתוך ה-activity. למה?

  32. 12:39

    דבר ראשון היא לא בדיוק קשורה לפעילות של האקטיביטי היא מחזירה לי איזה שהוא רנדום אימג' איידי שיכול לשמש אותי לכל מיני דברים אחרים.

  33. 12:49

    דבר שני זה פעילות לוגית היא לא הכי קשורה ל-UI לממשק המשתמש אני רוצה להוציא פעילויות לוגיות למחלקות אחרות. דבר שלישי אני רוצה לנקות כמה שיותר את האקטיביטי אני לא רוצה שיהיה לי פה כל מיני קודים לוגיים.

  34. 13:06

    דבר רביעי אולי בעוד אקטיביטיז אני ארצה את הפעילות הזאת, מה אני אעשה? קופי פלייסט עכשיו של הפונקציה וידביק אותה בכל מיני אקטיביטיז אחרים? לכן הדבר הנכון לעשות בפרויקט אמיתי זה לקחת את הפונקציה הזאת ופשוט להוציא אותה לאיזושהי מחלקה חיצונית שזה יהיה התפקיד שלה, לנהל את כל הפעילות של התמונות הרנדומניות.

  35. 13:27

    אז בואו נעשה את זה. בואו ניגש לתיקייה של האתר, נוסיף מחלקה חדשה, נקרא לה image manager, היא מנהלת לי את התמונות, נחזור בחזרה, נגזור את כל הפונקציה הזאת, נדביק אותה בתוך המחלקה עם כל הפאקג' הזה שצריך, נגדיר אותה כפאבליק וסטטיק כי אנחנו רוצים

  36. 13:55

    לקרוא לה בלי ליצור אובייקט מהמחלקה אימג'. הרי הגיוני שאם אנחנו לא משתמשים במשתני מחלקה, אז הגיוני שהפונקציה שלנו תהיה פונקציה סטטית ברוב המקרים, כן?

  37. 14:11

    במקרה הזה אני רוצה שהיא תהיה סטטית גם בכדי שיהיה לי ממש נוח לקרוא לה. אם אני חוזר בחזרה אז כמובן הפונקציה הזאת כבר לא נמצאת אצלי באקטיביטי. בשביל לקרוא לה אני צריך להגדיר את השם image-manager נקודה והנה יש לנו פה את הפונקציה getRandomImageID זאת אומרת אין שום בעיה מתוך האקטיביטי להפעיל את הפונקציה הזאתי זה ממש דבר נוח

לקורס המלא: קורס פיתוח אפליקציות לאנדרואיד

ההרצאה הקודמת: Typos

ההרצאה הבאה: The Listener Pattern

הרצאות קשורות מקורסים אחרים

  • קורס ריאקט - Context
  • מה זה console application
  • Application object
  • TS Remote Application

קורסים נוספים במסלול

  • קורס יסודות התכנות - שפת JAVA - קורס ג'אווה למתחילים
  • קורס פיתוח אפליקציות - לאייפון iPhone iOS - ב-Swift-Xcode
  • קורס פלאטר - Flutter - שפת DART של גוגל למובייל - פיתוח אפליקציות לאנדרואיד ואייפון
  • קורס PhoneGap - פיתוח אפליקציות לאנדרואיד ואייפון