PracticU

Wrong API Solutions

בלי כתוביותעם כתוביות
PracticU › קורס פיתוח אפליקציות - לאנדרואיד - Android - ב-JAVA › Wrong API Solutions
מילון מושגים:
API - ממשק תכנותי שמגדיר כיצד תוכנה אחת פונה לאחרת ומחליפה איתה נתונים ופעולות.
פונקציה - קטע קוד בעל שם שמבצע משימה מוגדרת, מקבל ערכי קלט (פרמטרים) ויכול להחזיר תוצאה. מאפשרת לארגן קוד ולהשתמש בו שוב.
Android - מערכת הפעלה מבוססת Linux לטלפונים ולמכשירים ניידים, שפותחה על ידי גוגל.
SDK - ערכת כלים לפיתוח: אוסף ספריות, כלים ותיעוד שמאפשרים לבנות תוכנה לפלטפורמה או שירות מסוימים.
אמולטור - תוכנה שמחקה מכשיר או סביבה אחרת, למשל כדי להריץ ולבדוק אפליקציית מובייל על המחשב.

Wrong API Solutions
מה קורה כשאפליקציה מוגדרת לתמוך בגרסאות API ישנות, אבל הקוד קורא לפונקציה שקיימת רק בגרסה חדשה יותר? Lint מסמן את זה כשגיאה, והאפליקציה עלולה לקרוס בטלפון עם גרסה ישנה. בהרצאה בונים דוגמה כזו ובודקים כמה פתרונות, ומגיעים לפתרון המומלץ.
הרקע
ב-minSdkVersion מגדירים את גרסת ה-API המינימלית שבה אפשר להתקין את האפליקציה. בדוגמה הוגדר 15. מי שיש לו API 14 לא יוכל להתקין בכלל. API level הוא חבילת הפונקציות והכלים של אנדרואיד, והוא הדרך הנוחה לדעת אם פונקציה מסוימת קיימת. פונקציה שנתמכת ב-21 קיימת גם ב-23, אבל ההפך לא בהכרח.
מה בנו בדוגמה
1. הצגת ה-API level: TextView שמציג את android.os.Build.VERSION.SDK_INT. על האמולטור יצא 23 ועל המכשיר האמיתי 21.
2. לחצן שצובע את הרקע: הלחצן קורא ל-getResources().getColor(R.color.background_color, getTheme()) ומציב את הצבע ב-LinearLayout. באמולטור זה עובד, אבל במכשיר האמיתי האפליקציה קורסת.
3. האזהרה של Lint: Call requires API level 23 (current min is 15). השגיאה בקריסה: NoSuchMethodError, כלומר הפונקציה getColor בצורה הזו לא קיימת במכשיר.
הפתרונות שנבדקו
1. להעלות את minSdk ל-23: משנים את minSdkVersion בקובץ build.gradle שבתיקיית app ועושים Sync. האזהרה נעלמת, אבל ההתקנה על המכשיר עם API 21 נכשלת (installation failed since app's minimum SDK version API 23 is newer). זה גם מפסיד לקוחות, ולכן כדאי לחשוב איזו גרסה באמת נדרשת. המרצה החזיר ל-15.
2. Disable Inspection: מסתיר את האזהרה רק זמנית ורק בהרצה הנוכחית. אחרי סגירה ופתיחה מחדש של הפרויקט היא חוזרת, והקריסה נשארת. לא עוזר.
3. @SuppressLint("NewApi"): משתיק את סוג האזהרה הזה. הוא רק מסתיר, והקריסה במכשיר האמיתי נשארת.
4. @TargetApi(Build.VERSION_CODES.M): דומה, אבל מצהיר שהפונקציה נתמכת מ-Marshmallow (API 23) ומעלה. הוא טוב יותר מ-SuppressLint, כי אם תשתמשו בהמשך בפונקציה של API 24 Lint עדיין יתריע. מתאים רק אם בטוחים שהמשתמש לא יגיע לקוד על מכשיר ישן, למשל כשמציגים את הלחצן רק מ-API 23.
5. Surround with if (הפתרון המומלץ): עוטפים את הקריאה בבדיקה של Build.VERSION.SDK_INT מול Build.VERSION_CODES.M. אם הגרסה מתאימה קוראים לפונקציה החדשה, ובמקרה אחר (else) קובעים ערך ברירת מחדל (fallback), בדוגמה Color.RED. כך האפליקציה עובדת בשני המכשירים.
שימו לב
- Lint מציג את הבעיה כ-error, אבל האפליקציה עדיין רצה, ולכן קל להתעלם ממנה ולהגיע לקריסה אצל לקוח.
- כדאי להגדיר minSdk נמוך ככל האפשר כדי להגיע ליותר משתמשים, אבל לא נמוך עד שחסרות פונקציות קריטיות. למשל אם האפליקציה חייבת טביעת אצבע, ה-minSdk חייב להתאים לה.
עכשיו אפשר לטפל בפונקציה שקיימת רק ב-API חדש בעזרת בדיקת גרסה וערך חלופי, ולהחליט במודע איזו גרסת minSdk להגדיר.
השיעור הבא בקורס: Typos

פרקי ההרצאה: Wrong API Solutions

  1. 00:00

    חוסר התאמה בין API Level לפונקציות

  2. 00:43

    Minimum SDK בפרויקט חדש

  3. 03:42

    הצגת ה-API Level של המכשיר

  4. 05:34

    מה זה API Level

  5. 06:51

    קריאת SDK_INT מהקוד

  6. 08:01

    הרצה באמולטור ובמכשיר אמיתי

  7. 09:54

    לחצן לשינוי צבע הרקע

  8. 14:14

    שגיאת Lint על פונקציה חדשה

תמלול ההרצאה: Wrong API Solutions

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

  1. 00:02

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

  2. 00:31

    חדש יותר. בואו נראה למה הכוונה ואיך לטפל במצב כזה. יש לנו פה פרויקט חדש ואנחנו רוצים לפתוח פרויקט שבואו נקרא לו wrong api solutions בואו נגדיר את הpackage בשם הסטנדרטי שלנו בואו נשמור אותו כ-wrong api solutions נעבור למסך הבא ובמסך הזה אנחנו רואים את ה-minimum sdk זאת אומרת מה ה-api level application

  3. 01:12

    programming interface כלומר החבילה של הפיתוח כשאנחנו משתמשים בה במינימום sdk מה זה אומר זה אומר איזו גרסה מינימלית יכולה להיות אצל המכשיר של הלקוח בכדי שהוא עדיין יוכל להוריד ולהתקין את האפליקציה שלנו אם לדוגמה אנחנו מפתחים עבור מינימום sdk של api 15 וליוזר יש api 15 ומעלה אין שום בעיה כי זה אומר

  4. 01:45

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

  5. 01:58

    זה ברור אבל מה קורה אם אנחנו עדיין מגדירים שאנחנו api 15 שזה אייס קרים סנדוויץ' אבל אנחנו באפליקציה שלנו משתמשים באיזושהי פונקציה שקיימת, בוא נניח ב-API 16 רק מ-API 16 הפונקציה הזאתי בעצם היא יצאה לעולם עכשיו יש פה איזושהי סתירה אנחנו הגדרנו שאנחנו רוצים שהאפליקציה הזאת

  6. 02:28

    תעבוד במינימום sdk של API 15 אבל אנחנו משתמשים עם פונקציה שלא קיימת ב-API 15 וזה אומר שאם ללקוח יש במכשיר שלו גרסת אנדרואיד של API 15 אז מה יקרה אם הוא בעצם יבוא וישתמש בפונקציה הזאת אז כמובן אתם יכולים לשאול את השאלה המתבקשת אז למה אתה משתמש בפונקציה הזאת אם היא לא קיימת ב-API 15?

  7. 02:53

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

  8. 03:18

    להשתמש במקום נקודתי באיזושהי פונקציה שלא קיימת כאן ואנחנו כן רוצים להשתמש בה אבל אנחנו חייבים לטפל במצב של מה קורה אם באמת היוזר יש לו API שלא מכיל את הפונקציה הזאת. אז בואו נמשיך וניצור את הפרויקט ניצור אותו לגמרי והנה הפרויקט נטען לגמרי בואו ניגש ונראה את ה-Main Activity layout, נסדר פה טיפה, הדבר הראשון שכדאי לנו לעשות זה קודם כל להציג את ה-API level

  9. 04:15

    של המכשיר הנוכחי שעליו האפליקציה רצה ואז נריץ את זה עם שני מכשירים ונראה כל אחד API level שונה וזה יעזור לנו בפיתוח. אז בואו נעשה כזה דבר, דבר ראשון יש לנו פה איזשהו טקסט view ומה שנעשה זה נגדיר לו ID טקסט view API level, נגדיר לו מרג'ין, נגדיר לו שהוא נמצא ב-Gravity Center Horizontal, אם יש לנו פה איזשהו טקסט אז אנחנו יכולים

  10. 04:57

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

  11. 05:19

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

  12. 05:46

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

  13. 06:08

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

  14. 06:24

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

  15. 06:39

    אוקיי, אז כל מה שאנחנו רוצים לעשות עכשיו זה לגשת לכאן, להגדיר פרייבט טקסט view, לאתר אותו, לגשת אליו, סט טקסט, ולתת לו api-level ואנחנו רוצים לשרשר את זה עם android.os.build.version.sdk.ind.

  16. 07:37

    וזאת יהיה המספר, המספר גרסה. קודם כל בואו נראה שאנחנו מטפלים כמו שצריך בהערות לינט, כבר אנחנו רואים שהשדה הזה אין שום צורך שהוא יהיה גלובלי מפני שאנחנו משתמשים איתו מקומית אז בואו ניתן ללינט לתקן את זה Alt Enter convert to local הוא נמחק נולד לנו כאן ומה שאנחנו רוצים לעשות זה להריץ אמולטור להריץ מכשיר אמיתי ולראות לכל אחד איזה API level יש לו אז בואו נפעיל

  17. 08:11

    את האמולטור הנה הוא רץ בואו נפעיל את המכשיר האמיתי הנה הוא רץ וכעת נריץ את האפליקציה על שני המכשירים בואו נבחר את שניהם Use same device for future launches.

  18. 08:34

    אמולטור, מכשיר. אז הנה האפליקציה רצה כבר על האמולטור ואנחנו רואים שה-API level של האמולטור הוא 23. והנה האפליקציה רצה על המכשיר האמיתי ואנחנו רואים שה-API level של המכשיר האמיתי הוא 21. אוקיי, זה מעניין.

  19. 08:53

    אז יש לנו כבר איזשהו שוני וזה בהחלט יכול להיות. ליוזר אחד יש גרסת אנדרואיד עם sdk של 23 ולאחד אחר יש sdk של 21 וכל אחד יכול להריץ בעצם פונקציות קצת אחרות.

  20. 09:11

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

  21. 09:26

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

  22. 10:09

    צובע את הצבע רקע של האפליקציה. בואו נגדיר את זה כאן בתוך ה-Strings כדי שלא יהיה לנו שום הערות כרגע. יש לנו פה String name set background זור, נגדיר שבקובץ ה-Strings יש לנו set background color, נגדיר text size בואו ניקח 20, נגדיר טקסט All Caps False איזשהו מרג'ין ו-On Click Set Background

  23. 11:03

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

  24. 11:59

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

  25. 12:34

    אוקיי, עכשיו יש לנו פה את הצבע Background Color ואנחנו רוצים לקחת אותו ולשים אותו בתוך ה-Linear Layout Main שלנו.

  26. 12:46

    אז בואו ניקח את ה-Linear Layout Main ואיך אנחנו מכניסים לתוכו צבע. דבר ראשון, מה שאנחנו רוצים לעשות זה לבנות אובייקט resources לפנות לפונקציה get resources שראינו בעבר שהתפקיד שלה זה לאתר את כל ה-resources שהאפליקציה משתמשת איתם.

  27. 13:09

    לאחר מכן אנחנו רוצים לפתוח איזשהו int color ולהגיע ל-resources get color ולתת לו r color ויש לנו פה את ה-background color שדיברנו עליו ואנחנו רוצים לעשות את זה ב-team הנוכחי.

  28. 13:34

    הפונקציה מקבלת אם שמתם לב גם איזה team אנחנו נמצאים אנחנו נמצאים ב-team הנוכחי ועכשיו אנחנו רוצים להיכנס ל-activity ולהגדיר ב-activity set background color הנה ה-color שלנו דבר ראשון בואו נריץ ונראה האם זה עובד כמו שצריך אז הנה אנחנו נמצאים באמולטור נלחץ על הלחצן קול עובד כמו שצריך הנה אנחנו נמצאים במכשיר

  29. 14:07

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

  30. 14:28

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

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

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

ההרצאה הבאה: Typos

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

  • תרגול על Java API
  • הסבר על מה זה ממשק - API
  • מוסכמות ב-REST API
  • הסבר על Google Map - API

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

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