
AsyncTask.AsyncTask: Thread של Java יכול לבצע קוד במקביל, אבל בדרך כלל מעדיפים AsyncTask, וההמשך יסביר למה.EditText למספר התחלתי וסופי, כפתור שמוצא את כל המספרים הראשוניים בטווח, ו-TextView בתוך ScrollView להצגת התוצאה.Long.parseLong (long, כי המשתמש עשוי להכניס מספר גדול מ-int), ורצים בלולאה for מההתחלה עד הסוף.PrimesHelper.isPrime: פונקציה סטטית שמחזירה false למספר קטן או שווה ל-1. היא בודקת חלוקה ללא שארית ממספרים מ-2 ועד שורש המספר (Math.sqrt), ואם מצאה מחלק מחזירה false, ואחרת true.StringBuilder עם פסיק, ובסוף התוצאה מוצגת ב-TextView עם setText.AsyncTask.הטקסט המלא של הדקות הראשונות בהרצאה «הצורך ב-Async Task» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
אנחנו מגיעים בנושא חדש, שהוא נושא מאוד נפוץ ומאוד שימושי בפיקציות אנדוויד, והנושא הזה נקרא Async Task. Async Task זאת מחלקה שמאפשרת לנו להריץ קטע קוד במקביל לשאר פעילות האפליקציה.
אז קודם כל, למה שנרצה לבצע קטע קוד במקביל? כי יכול להיות שאנחנו רוצים לבצע איזשהו קוד מסוים שלוקח פשוט הרבה זמן. אז מה יקרה אם אנחנו פשוט נריץ את הקוד הזה, נניח בתוך activity, בקוד של לחצן?
אם אנחנו נריץ את זה כחלק מהactivity, בגלל שהקוד הזה לוקח הרבה זמן, אז הוא בעצם יתקל לנו את הפעילות של האפליקציה. יוזר לדוגמה ילחץ על הלחצן ופשוט יצטרך להמתין הרבה זמן עד שכל האפליקציה תשתחרר.
מה שיקרה זה שהמסך יקפה לו והוא לא יכול לבצע שום דבר עם האפליקציה, כי פשוט ברקע היא מוציאה לפועל את הקוד הרב הזה. אז אנחנו נרצה לקחת את הקוד הזה ולהריץ אותו במקביל לפעילות של האפליקציה, זאת אומרת שהוא יוכל ללחוץ על הלחצון, ברקע הקוד מתבצע, ובמקביל הוא יוכל להמשיך לעבוד עם האפליקציה עד שהקוד יסתיים.
כאמור נעשה את זה רק אם זה כנראה ייקח לנו הרבה זמן. סיבה נוספת היא גישה לאינטרנט. אם אנחנו נגישים לאינטרנט, יכול להיות שהדבר הזה גם כן ייקח הרבה זמן ויכול להיות שלא.
אבל מגרסה מסוימת של אנדרואיד, קבעו שאם אתם נגשים לאינטרנט, אתם חייבים לבצע את הגישה הזאת במקביל ולא כחלק מפעילות האפליקציה או ליתר דיוק מפעילות ה-UI, ממשק המשתמש.
אז גם כאן אנחנו נרצה להריץ את הקוד הזה במקביל. עכשיו, אם קצת נחשפתם לג'אבה, אתם יודעים שקיים משהו שנקרא thread. Thread זאת מחלקה שגם היא מאפשרת לבצע קטע קוד במקביל, ואנחנו יכולים להשתמש איתה וזה ממש בסדר.
אבל אנחנו תכף נראה למה אנחנו נעדיף להשתמש הרבה פעמים ב-Async Task ולא ב-Thread. אז קודם כל, בואו נסתכל על דוגמה שיש לנו כאן, ונראה למה אנחנו בעצם רוצים להריץ קטע קוד במקביל, איך אפשר להסתכל את הקוד הזה בעזרת thread ולמה אנחנו נבחר ב-AsyncTask ולא ב-Thread.
אז קודם כל יש לנו כאן את האקטיביטי ומה שיש לנו פה זה פשוט ממשק משתמש שיש לו כאן איזושהי תיבה EditText לקבלת מספר התחלתי, תיבה נוספת לקבלת מספר סופי ולחצן למציאת כל המספרים הראשוניים בין שני המספרים שהוכנסו.
המספר ראשוני זה מספר שמתחלק רק בעצמו ובאחד בלבד, ואין שום מספר אחר שמחלק אותו בלי שערית. אז מה בעיה עם התרגיל הזה? אם היוזר מכניף טווח מספרים מאוד מאוד גדול, למצוא את כל המספרים ביניהם ייקח זמן מפני שבשביל לדעת האם מספר מסוים הוא ראשוני כן או לא, אנחנו נצטרך לרוץ על כל המספרים עד אליו ולראות אם יש מישהו שמחלק אותו בלי שערית.
והפעילות הזאת לוקחת הרבה זמן למספר אחד. אז תחשבו, מייקרים, יש לנו פה טווח מאוד מאוד גדול. מה אנחנו רוצים לבצע עכשיו? בסיום המציאה של כל המספרים הראשוניים, אנחנו רוצים להציב אותם כאן בתוך הטקסט-וו הזה, ובגלל שיכול להיות שיהיו לנו הרבה מספרים, אז עטפנו אותו פה בסקרול-וו.
אוקיי, אז בואו ניכנס לקוד, ונראה קודם כל מה קורה אם אנחנו פשוט כותבים את זה, כחלק מהאקטיביטי, מבלי לבצע את זה במקביל, ואז נראה איך כל המערכת הזאת מתנהגת.
הנה יש לנו פה את הלחצן, בואו ניכנס אליו, ויש לנו כאן למעלה את ה-edit text start number, end number, וה-text view להצגת כל המספרים, איתרנו אותם כאן, ואנחנו מעוניינים בלחצן, פשוט לרוץ מההתחלה עד הסוף ולמצוא את כל המספרים הראשונים ביניהם.
אז בואו קודם כל נקבל את המספרים האלה, בואו ניקח כאן איזשהו משתנה long start, מפני שהיוזר יכול להכניס מספר שהוא יותר גדול, לדוגמה מ-integer. אנחנו רוצים לגשת ל-long, נקודה parse long, ולתת לו edit text start, get text, נהפוך אותו לטו-סטרינג, נשכפל את הכל גם ל-end, זה המספר הסופי, ויש לנו כאן editText end, והנה יש לנו את שני המספרים.
מה שאנחנו רוצים לעשות זה לרוץ בלולאה, בואו נעשה for i, ואנחנו רוצים שה-i לא יהיה integer אלא יהיה long, אנחנו רוצים שהוא יתחיל מ-start ושיהיה קטן שווה ל-end, והנה יש לנו פה לולאה שסורקת את כל הטווח.
עכשיו, כל מספר שאנחנו סורקים בטווח, אנחנו רוצים קודם כל לבדוק אם המספר הזה ראשוני כן או לא. אז בשביל לבדוק אם מספר ראשוני, אנחנו צריכים לקחת אותו ולהתחיל למצוא, כאמור, את כל המספרים משתיים למעשה ועד אליו, ולראות האם יש מישהו שמחלק אותו בלי שירית.
אז בשביל שיהיה לנו פשוט ונקיר יותר בקוד, בואו פשוט נצרף מחלקה, נקרא לה Primes Helper. פריים זה מספר ראשוני, בואו נגדיר כאן איזושהי פונקציה, סטטית, בוליאן, ונקרא לה is prime.
והיא תקבל איזשהו מספר long, ותבדוק אם הוא ראשוני. איך אנחנו עושים את זה? אנחנו לוקחים לימיט, עד לאן אנחנו רוצים לבדוק.
אז למעשה, לפי נוסחה מתמטית, אנחנו לא צריכים לבדוק את כל המספרים משתיים עד אליו, אלא מספיק עד השורש שלו. אז בואו ניקח את math.square root. ונשלח את המספר, והנה יש לנו את השורש, זה מבחינה מתמטית יעבוד עכשיו אנחנו רוצים לרוץ על כל המספרים משתיים למעשה ועד ללימיט, קטן שווה ללימיט ולבדוק האם יש איזשהו מספר שמחלק אותו אם נעמודולו i הוא 0, מצאנו מישהו שמחלק
אותו בלי שערית, כבר אנחנו יכולים להחזיר false אם סיימנו את כל הלולה הזאת ולא מצאנו שום דבר אנחנו יכולים להחזיר true