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

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

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

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

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

דרישות מוקדמות

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

מעקב אחרי מיקומי רשימות שהוקצו

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

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

צריך לשמור על המצב הבא בווידג'ט:

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

בדוגמה הבאה מתבצע מעקב אחרי מיקומי הרשימה שהוקצו לכל מודעה במטמון:

// Maximum number of banner ad instances kept in the cache.
static const int _cacheSize = 8;

// Spacing between banner ads. For example, index 0, 6, 12, and so on
// display ads.
static const int _adInterval = 6;

// The cache of allocated BannerAd instances.
final List<BannerAd> _banners = [];

// Maps each BannerAd instance to its currently assigned list item position.
final Map<BannerAd, int> _bannerPositions = {};

// Stores the platform-resolved size of each loaded banner ad.
final Map<BannerAd, AdSize> _bannerSizes = {};

בחירת גודל המטמון

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

כדי לבחור גודל:

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

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

איך בודקים אם מודעה מוצגת במסך

כל הכיתות Google Mobile Ads Flutter Plugin שמעבדות תצוגות של פלטפורמות מטמיעות את הכיתה AdWithView ומספקות getter של isMounted. לפני שמקצים מחדש מודעה שנשמרה במטמון למיקום ברשימה, צריך לבדוק את isMounted הפונקציה getter כדי לוודא שהמודעה יצאה מהמסך ושאפשר להשתמש בה שוב.

איך מאחזרים מודעת באנר ומשתמשים בה מחדש

כשברשימה נשלחת בקשה להצגת באנר במיקום מסוים, מבצעים את הפעולות הבאות:

  1. שימוש חוזר במודעה שכבר הוקצתה למיקום הזה, אם קיימת כזו.
  2. אם המטמון לא מלא, שולחים בקשה להצגת מודעה.
  3. אם המטמון מלא, בוחרים מודעה במטמון ומוודאים שהערך של הפונקציה getter‏ isMounted הוא false לפני שמקצים מחדש את המודעה.
  4. קוראים לפונקציה dispose() בכל מודעה במטמון כשהווידג'ט מוסר מעץ הווידג'טים.

בדוגמה הבאה מאחזרים מודעת באנר וממחזרים אותה:

BannerAd _getRecycledBannerAd(BuildContext context, int bannerPosition) {
  // 1. If an ad is already mapped to this position, reuse it.
  final BannerAd? existingBanner = _bannerPositions.entries
      .firstWhereOrNull((entry) => entry.value == bannerPosition)
      ?.key;
  if (existingBanner != null) {
    return existingBanner;
  }

  // 2. If the cache is not full, allocate a new ad instance.
  if (_banners.length < _cacheSize) {
    final BannerAd newBanner = _createBannerAd(context);
    _banners.add(newBanner);
    _bannerPositions[newBanner] = bannerPosition;
    return newBanner;
  }

  // 3. Select an existing ad from the cache using modulo arithmetic.
  final BannerAd targetBanner = _banners[bannerPosition % _cacheSize];

  // 4. Verify the ad is detached from the screen before recycling.
  if (targetBanner.isMounted) {
    // If still on screen during fast scrolls, allocate a temporary instance.
    return _createBannerAd(context);
  } else {
    // Safe to reuse: reassign to the new position.
    _bannerPositions[targetBanner] = bannerPosition;
    return targetBanner;
  }
}

דוגמה מלאה זמינה במאמר Google Mobile Ads Flutter Plugin.