עבור לתוכן

איך לדעת כשמשתנה משתנה? JAVA

Featured Replies

פורסם

אהלן,

יש לי תוכנית בJAVA שהגדרתי באחת הפונקציות שבסיום הפונקציה משתנה בשם Finish יהיה שווה לtrue.

אני קורא למשתנה הזה במחלקה אחרת ובודק למה הוא שווה.

אבל, אני רוצה במחלקה החדשה, בכל פעם שהוא משתנה לדעת למה הוא השתנה (true/false).

אני רוצה שבתוך הפונקציה שבמחלקה B הIF יקרה רק כשהמשתנה A.finish יהיה שווה לtrue.

תודה רבה!


public class A
{
boolean finish;

public void functionA
{
.
.
.
.
finish = true;
}

}


public class B
{
boolean finish;

public void functionB
{
if(A.finish)
{
// TODO
}

}

}

פורסם

אתה מכיר ת'רדים ואת הפונקציה notify?

פורסם
  • מחבר

ת'רדים כן, את הפונקציה notify() עדיין לא.

שמעתי משהו על Observer אבל לא הבנתי כ"כ איך זה עובד.

פורסם

הדרך הכי בסיסית:

אתה מגדיר ב-B פונקציה בשם notify. הפונקציה הזו תהיה ה"הודעה" ש-finish התעדכן, והמימוש שלה יהיה מה שאתה רוצה שיקרה כשהמשתנה משתנה.

אתה דואג של-A יהיה שדה מטיפוס B, שיהיה אפשר להגדיר אותו מבחוץ (באמצעות פונקציה בשם setB או משהו כזה).

ב-A, בכל פעם שמשנים את finish, אתה קורא ל-B.notify. הדרך הנכונה לעשות את זה היא ליצור פונקציית setter ל-finish שעושה את שתי הפעולות יחד.

כל מה שנותר הוא שכשאתה יוצר אובייקט מטיפוס A, להעביר אליו את האובייקט מטיפוס B.

אם אתה רוצה להימנע מתלות מעגלית (בפתרון הנ"ל צריך ש-A יכיר את B וגם ש-B יכיר את A), אתה משתמש בממשק Observer - תגדיר ממשק כזה עם פונקציה אחת בלבד (notify), תדאג ש-B יממש את הפונקציה הזו, ושל-A במקום setB יהיה setObserver שמקבלת אובייקט מטיפוס Observer במקום מטיפוס B.

נערך על-ידי שניצל

פורסם
  • מחבר
הדרך הכי בסיסית:

אם אתה רוצה להימנע מתלות מעגלית (בפתרון הנ"ל צריך ש-A יכיר את B וגם ש-B יכיר את A), אתה משתמש בממשק Observer - תגדיר ממשק כזה עם פונקציה אחת בלבד (notify), תדאג ש-B יממש את הפונקציה הזו, ושל-A במקום setB יהיה setObserver שמקבלת אובייקט מטיפוס Observer במקום מטיפוס B.

לא הבנתי מה אני עושה בA.

אני מגדיר משתנה מסוג Observer עושה Setter, קורא לו איפה שאני צריך ומציב את המשתנה בתוך הSetter שלו?!

פורסם

ככה:

interface Observer {
void notify();
}


class A {
boolean finish;
Observer obs;
public void setObserver(Observer obs) {
this.obs = obs;
}

private void setFinish(boolean value) {
finish = value;
if (obs != null) { obs.notify(); }
}
}


class B implements Observer {
public void notify() {
// do some stuff here
}
}




main:


A a = new A();
B b = new B();
a.setObserver(b);

השמטתי כמובן את כל שאר הקוד הנחוץ, אני מניח שתבין מה לעשות. עכשיו בתוך A, במקום לעשות finish=true תעשה (setFinish(true וזה ידאג לקרוא ל-b.notify.

פורסם
  • מחבר

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

אבל כנראה שזה נובע מאי דיוקים בשאלה.

Class A is extends Application מה שאומר שהוא מתחיל לפעול איך שהאפליקציה עולה.

Class B הוא AsyncTask בתוך Class אחר.

1.יש Class שמתחבר לשרת והוא מרחיב את Application.

2. יש Class שהוא ListActivity וישלו Adpter.

3. בתוך הClass של ListActivity יש Class שהוא AsyncTask.

4. בפונקציה onPost האחרונה של AsyncTask אני רוצה שProgressDialog יעלם אם המשתנה הבוליאני שבClass A(זה שמרחיב את Application) הוא true.

אבל מה שקורה, שבגלל שהפונקציה שרצה בClass A היא background ולוקח לזה זמן אז המשתנה false כשהAsyncTask מגיע אליו.

ניסיתי לשים Observer שם אבל זה תוקע את האפליקציה.

מקווה שהסברתי את זה הפעם קצת יותר טוב. :)

תודה רבה!

עריכה:

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

נערך על-ידי yagelk

פורסם

שניצל הסביר מצוין את הקונספט וגם נתן לך מימוש.זה לא עובד לך כי (כנראה) פספסת כמה דברים בשימוש בכלים של אנדרויד. למה ה-Application class שלך מתחבר לשרת? הוא מביא את הנתונים? למה? אם מדובר על רשימה להציג במסך אז שה-Activity שלך יביא את זה. מצד שני אני רואה שיש לך AsyncTask - הוא באקטיבי אני מניח- מה אתה עושה שם אם לא להביא את הנתונים מהשרת? מי בכלל מציג את ה-progressDialog?

הארכיטקורה שבחרת ממש לא ברורה, כנראה כי לא ברור לי מה המשימה הכללית שאתה מנסה לעשות. ממה שאני רואה יש רשימה שמביאים מהשרת ומראים ליוזר. מקרה פשוט של Activity עם מנגנון טעינה בסיסי ברקע - כנראה ש-AsyncTask יהיה באמת הכי פשוט ורלוונטי. למה להרחיב את Application ועוד לגרום לו לתקשורת עם שרת? יש לך עוד איזה דרישות שלא פירטת?

פורסם
  • מחבר

שניצל באמת הסביר את זה מעולה והבנתי.

אגב, אם לא אמרתי תודה, אז תודה שניצל!

לעניינו,

זה מייבא את הנתונים לתוך Vector לעוד כמה שימושים עם הנתונים במסכים שונים.

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

הApplication class לא מביא את הנתונים אוטומטי אלא יש פונקציה שהיא אחראית על זה, ולצורך העניים אני קורא לה בMainActivity.

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

נערך על-ידי yagelk

פורסם

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

האקטיבי קורא לפונקציה כלשהי (לא משנה איפה היא נמצאת) שמביאה נתונים. לפני שאתה קורא לפונקציה תציג ProgressDialog ואחרי שאתה מסיים להביא את הנתונים תעלים אותו. לפי התאור שלך אני מניח שהמתודה שמביאה את הנתונים היא לא Blocking - תדאג שהיא תהיה והסיפור נהיה מאד פשוט, לא? איפה הבעיה בעצם?

פורסם
  • מחבר
ככה:


main:


A a = new A();
B b = new B();
a.setObserver(b);

השמטתי כמובן את כל שאר הקוד הנחוץ, אני מניח שתבין מה לעשות. עכשיו בתוך A, במקום לעשות finish=true תעשה (setFinish(true וזה ידאג לקרוא ל-b.notify.

שניצל וניצן

תודה רבה!

מסתבר שאת ה3 שורות האחרונות לא יישמתי כמו שצריך.

הכל עובד חלק. תודה!

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים