@@ -56,17 +56,43 @@ class _DecoratorCandidate {
5656/// This service implements a multi-stage pipeline to ensure that the most
5757/// relevant and timely items are injected in a logical and non-intrusive way.
5858///
59- /// **Ad Injection Architecture:**
60- /// In the current architecture, the responsibility for loading and managing
61- /// native ads is completely decoupled from this service and the BLoC layer.
62- /// Instead of injecting fully loaded `AdFeedItem` objects, this service now
63- /// only injects stateless `AdPlaceholder` markers into the feed.
59+ /// ### Ad Injection Architecture Explained
6460///
65- /// The actual ad loading and lifecycle management (including caching and
66- /// disposal) is handled by the `AdLoaderWidget` in the UI layer. This
67- /// simplifies this service's role and prevents the BLoC from holding onto
68- /// stateful native ad objects, which was the root cause of previous crashes
69- /// and performance issues during scrolling.
61+ /// To solve lifecycle-related crashes and improve performance, the responsibility
62+ /// for loading and managing native ads is completely decoupled from this service
63+ /// and the BLoC layer. The architecture follows this robust, multi-step flow:
64+ ///
65+ /// 1. **`FeedDecoratorService` (This Class):**
66+ /// Instead of loading and injecting fully-loaded, stateful native ad
67+ /// objects, this service's only role is to inject simple, stateless
68+ /// `AdPlaceholder` markers into the feed list at appropriate intervals.
69+ /// This keeps the BLoC's state clean and lightweight.
70+ ///
71+ /// 2. **`HeadlinesFeedPage` (UI Layer):**
72+ /// The `ListView` in the UI receives the mixed list of content and
73+ /// placeholders from the BLoC. When it encounters an `AdPlaceholder`, it
74+ /// renders an `AdLoaderWidget`.
75+ ///
76+ /// 3. **`AdLoaderWidget` (The Ad Loader):**
77+ /// This stateful widget is responsible for the entire lifecycle of a single
78+ /// ad slot. It first checks the `AdCacheService` for a valid, pre-loaded
79+ /// ad. If not found, it requests a new one from the `AdService`.
80+ ///
81+ /// 4. **`AdFeedItemWidget` (The Dispatcher):**
82+ /// Once the `AdLoaderWidget` has a successfully loaded `NativeAd` object,
83+ /// it passes this ad to the `AdFeedItemWidget`. This widget acts as a
84+ /// dispatcher, inspecting the ad's provider type (`admob`, `placeholder`,
85+ /// etc.) and selecting the correct rendering widget.
86+ ///
87+ /// 5. **`AdmobNativeAdWidget` (The Renderer):**
88+ /// This is the final widget in the chain, responsible for rendering the
89+ /// actual AdMob native ad. Crucially, it no longer contains any disposal
90+ /// logic. Its lifecycle is now entirely managed by the `AdCacheService`,
91+ /// which prevents the ad from being disposed of when it scrolls out of
92+ /// view, thus fixing the crash.
93+ ///
94+ /// This architecture ensures a clean separation of concerns, improves stability,
95+ /// and makes the ad system more maintainable and extensible.
7096class FeedDecoratorService {
7197 /// Creates a [FeedDecoratorService] .
7298 ///
0 commit comments