在新聞動態或社群動態等長或無限捲動清單中,為每個項目位置建立橫幅廣告可能會導致記憶體消耗量過高和 UI 延遲。為提升效能,請使用橫幅廣告回收機制,維持 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 = {};
選擇快取大小
將快取大小設為大於可同時顯示在畫面上的廣告數量上限。如果快取小於該大小,選取用於回收的廣告通常仍會顯示,且應用程式會分配額外廣告,而不是重複使用廣告。
如要選擇大小,請按照下列步驟操作:
- 將可視區域高度除以一個廣告間隔的高度,即可估算畫面一次可顯示多少廣告。
- 在快速捲動期間,為仍在卸載的廣告新增空間。
- 如果發現選取要回收的廣告仍在畫面上,請增加快取大小。
本頁的範例每六列會顯示一則廣告,並使用八個項目的快取。這個範例會為螢幕上同時顯示的少數廣告保留空間。
檢查廣告是否顯示在畫面上
所有用於算繪平台檢視區塊的 Google Mobile Ads Flutter Plugin 類別都會導入 AdWithView 類別,並提供 isMounted getter。將快取廣告重新指派給清單位置前,請檢查 isMounted 擷取器,確認廣告已捲動至螢幕外,可安全重複使用。
擷取及回收橫幅廣告
當清單要求特定位置的橫幅時,請執行下列操作:
- 重複使用已指派給該位置的廣告 (如有)。
- 如果快取未滿,請請求廣告。
- 如果快取已滿,請選取快取廣告,並在重新指派廣告前,確認
isMountedgetter 是false值。 - 當小工具從小工具樹狀結構中移除時,請對快取中的每個廣告呼叫
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 範例。