admanagekit-mcp-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/content/README.md +851 -0
- package/content/docs/AD_FREQUENCY_CONTROL.md +450 -0
- package/content/docs/AD_LOADING_STRATEGIES.md +369 -0
- package/content/docs/API_REFERENCE.md +734 -0
- package/content/docs/APP_PURCHASE_GUIDE.md +704 -0
- package/content/docs/BANNER_AD_IMPROVEMENTS.md +325 -0
- package/content/docs/COMPOSE_INTEGRATION.md +477 -0
- package/content/docs/CONFIGURATION_USAGE.md +168 -0
- package/content/docs/INTERSTITIAL_BUILDER_GUIDE.md +518 -0
- package/content/docs/JAVA_USAGE_GUIDE.md +785 -0
- package/content/docs/LOADING_STRATEGY_EXAMPLES.md +463 -0
- package/content/docs/NATIVE_AD_MANAGER_ENHANCEMENTS.md +347 -0
- package/content/docs/NATIVE_AD_PRELOADING.md +467 -0
- package/content/docs/NATIVE_TEMPLATE_VIEW.md +413 -0
- package/content/docs/app-open-ads.md +412 -0
- package/content/docs/interstitial-ads.md +269 -0
- package/content/docs/native-ads-caching.md +182 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.1.0.md +156 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.2.0.md +248 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.3.0.md +280 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.5.0.md +73 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.6.0.md +265 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.7.0.md +168 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.8.0.md +153 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.9.0.md +479 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.0.0.md +343 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.1.0.md +131 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.3.0.md +252 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.3.2.md +215 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.3.3.md +116 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.3.4.md +142 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.3.5.md +94 -0
- package/content/docs/rewarded-ads.md +623 -0
- package/content/wiki/Ad-Loading-Strategies.md +209 -0
- package/content/wiki/App-Open-Ads.md +189 -0
- package/content/wiki/Banner-Ads.md +133 -0
- package/content/wiki/Billing-Integration.md +69 -0
- package/content/wiki/Configuration.md +252 -0
- package/content/wiki/Consumable-Products.md +166 -0
- package/content/wiki/Home.md +144 -0
- package/content/wiki/Interstitial-Ads.md +313 -0
- package/content/wiki/Jetpack-Compose.md +270 -0
- package/content/wiki/NativeAdManager.md +220 -0
- package/content/wiki/Purchase-Categories.md +94 -0
- package/content/wiki/Rewarded-Ads.md +420 -0
- package/content/wiki/Subscription-Upgrades.md +278 -0
- package/content/wiki/Subscriptions.md +368 -0
- package/content/wiki/_Footer.md +3 -0
- package/content/wiki/_Sidebar.md +18 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +18 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/code-generation.d.ts +2 -0
- package/dist/tools/code-generation.js +264 -0
- package/dist/tools/code-generation.js.map +1 -0
- package/dist/tools/documentation.d.ts +2 -0
- package/dist/tools/documentation.js +202 -0
- package/dist/tools/documentation.js.map +1 -0
- package/dist/types.d.ts +18 -0
- package/dist/types.js +83 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/doc-loader.d.ts +17 -0
- package/dist/utils/doc-loader.js +245 -0
- package/dist/utils/doc-loader.js.map +1 -0
- package/dist/utils/search.d.ts +2 -0
- package/dist/utils/search.js +62 -0
- package/dist/utils/search.js.map +1 -0
- package/dist/utils/templates.d.ts +60 -0
- package/dist/utils/templates.js +793 -0
- package/dist/utils/templates.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
# Release Notes - v3.0.0
|
|
2
|
+
|
|
3
|
+
## Highlights
|
|
4
|
+
|
|
5
|
+
- **Ad Pool System**: Load multiple interstitial ad units into a pool for maximum show rate
|
|
6
|
+
- **Smart Splash Ads**: New `showOrWaitForAd()` method handles all splash screen scenarios automatically
|
|
7
|
+
- **App Open Ad Prefetching**: Prefetch ads before external intents for instant display on return
|
|
8
|
+
- **Cross-Ad-Unit Fallback**: Native ads can fall back to any cached ad when specific unit unavailable
|
|
9
|
+
- **New Template**: `MEDIUM_HORIZONTAL` - 55/45 media-content horizontal split layout
|
|
10
|
+
- **Modern Window APIs**: Replaced deprecated `systemUiVisibility` with `WindowInsetsController`
|
|
11
|
+
- **Enhanced Firebase Analytics**: Session-level tracking for fill rate, show rate, and ad impressions
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## New Features
|
|
16
|
+
|
|
17
|
+
### AdManager - Ad Pool System
|
|
18
|
+
|
|
19
|
+
Load multiple interstitial ad units into a pool. When showing, returns ANY available ad - maximizing show rate:
|
|
20
|
+
|
|
21
|
+
```kotlin
|
|
22
|
+
// Load multiple ad units for redundancy
|
|
23
|
+
AdManager.getInstance().loadMultipleAdUnits(context, "high_ecpm", "medium_ecpm", "fallback")
|
|
24
|
+
|
|
25
|
+
// Or load individually
|
|
26
|
+
AdManager.getInstance().loadInterstitialAd(context, "unit_a")
|
|
27
|
+
AdManager.getInstance().loadInterstitialAd(context, "unit_b")
|
|
28
|
+
|
|
29
|
+
// Show ANY available ad from the pool
|
|
30
|
+
AdManager.getInstance().showInterstitialIfReady(activity, callback)
|
|
31
|
+
|
|
32
|
+
// Pool utilities
|
|
33
|
+
AdManager.getInstance().getPoolSize() // Number of ready ads
|
|
34
|
+
AdManager.getInstance().getReadyAdUnits() // Set of ad unit IDs with ready ads
|
|
35
|
+
AdManager.getInstance().isReady("unit_a") // Check specific unit
|
|
36
|
+
AdManager.getInstance().clearAdPool() // Clear all ads (e.g., on purchase)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Key behaviors:**
|
|
40
|
+
- Each ad unit loads independently (no blocking)
|
|
41
|
+
- Duplicate load requests for same unit are automatically skipped
|
|
42
|
+
- Auto-reloads the specific unit that was shown
|
|
43
|
+
- Thread-safe with `ConcurrentHashMap`
|
|
44
|
+
|
|
45
|
+
### AdManager - Smart Splash Ads
|
|
46
|
+
|
|
47
|
+
New `showOrWaitForAd()` method handles all splash screen scenarios in a single call:
|
|
48
|
+
|
|
49
|
+
```kotlin
|
|
50
|
+
// In your SplashActivity
|
|
51
|
+
private fun showSplashAd() {
|
|
52
|
+
AdManager.getInstance().showOrWaitForAd(
|
|
53
|
+
activity = this,
|
|
54
|
+
callback = object : AdManagerCallback() {
|
|
55
|
+
override fun onNextAction() {
|
|
56
|
+
navigateToMainActivity()
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
timeoutMillis = 10_000,
|
|
60
|
+
showDialogIfLoading = true
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Automatic behavior:**
|
|
66
|
+
| Scenario | What happens |
|
|
67
|
+
|----------|--------------|
|
|
68
|
+
| Ad is READY | Shows immediately |
|
|
69
|
+
| Ad is LOADING | Waits with optional dialog, shows when ready or times out |
|
|
70
|
+
| Neither | Loads fresh ad with loading dialog |
|
|
71
|
+
|
|
72
|
+
**Recommended splash flow:**
|
|
73
|
+
```kotlin
|
|
74
|
+
// Option 1: Preload in Application, smart show on splash
|
|
75
|
+
class MyApp : Application() {
|
|
76
|
+
override fun onCreate() {
|
|
77
|
+
AdManager.getInstance().loadInterstitialAd(this, adUnitId)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
class SplashActivity : AppCompatActivity() {
|
|
82
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
83
|
+
// Ad may already be loaded from Application
|
|
84
|
+
AdManager.getInstance().showOrWaitForAd(this, callback, 10_000)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Option 2: Load and show on splash (all-in-one)
|
|
89
|
+
class SplashActivity : AppCompatActivity() {
|
|
90
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
91
|
+
// Works even with no preloading
|
|
92
|
+
AdManager.getInstance().showOrWaitForAd(this, callback, 10_000)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### AppOpenManager - Ad Prefetching
|
|
98
|
+
|
|
99
|
+
Prefetch app open ads before launching external intents:
|
|
100
|
+
|
|
101
|
+
```kotlin
|
|
102
|
+
// Before launching camera, browser, etc.
|
|
103
|
+
appOpenManager.prefetchNextAd { started ->
|
|
104
|
+
if (started) Log.d("ADS", "Prefetch started")
|
|
105
|
+
}
|
|
106
|
+
startActivityForResult(cameraIntent, REQUEST_CODE)
|
|
107
|
+
|
|
108
|
+
// When user returns:
|
|
109
|
+
// - If ad is ready: shows instantly (no welcome dialog)
|
|
110
|
+
// - If still loading: welcome dialog waits for it
|
|
111
|
+
|
|
112
|
+
// Check loading state
|
|
113
|
+
if (appOpenManager.isAdLoading()) {
|
|
114
|
+
// Ad is being fetched
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### NativeAdManager - Cross-Ad-Unit Fallback
|
|
119
|
+
|
|
120
|
+
When enabled, native ads can fall back to ANY cached ad from ANY ad unit:
|
|
121
|
+
|
|
122
|
+
```kotlin
|
|
123
|
+
// Enable in config
|
|
124
|
+
AdManageKitConfig.enableCrossAdUnitFallback = true
|
|
125
|
+
|
|
126
|
+
// Now getCachedNativeAd will:
|
|
127
|
+
// 1. Try exact ad unit match
|
|
128
|
+
// 2. Try same base ad unit variants
|
|
129
|
+
// 3. Try ANY cached ad from any unit (if enableCrossAdUnitFallback = true)
|
|
130
|
+
val ad = NativeAdManager.getCachedNativeAd(adUnitId, enableFallbackToAnyAd = true)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Enhanced Firebase Analytics
|
|
134
|
+
|
|
135
|
+
Session-level tracking for comprehensive ad performance metrics:
|
|
136
|
+
|
|
137
|
+
```kotlin
|
|
138
|
+
// Get current session stats
|
|
139
|
+
val stats = AdManager.getInstance().getAdStats()
|
|
140
|
+
// Returns: session_requests, session_fills, session_impressions,
|
|
141
|
+
// fill_rate_percent, show_rate_percent, pool_size, ready_units
|
|
142
|
+
|
|
143
|
+
// Reset for new session
|
|
144
|
+
AdManager.getInstance().resetAdStats()
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Logged events:**
|
|
148
|
+
| Event | Description |
|
|
149
|
+
|-------|-------------|
|
|
150
|
+
| `ad_request` | When ad load is initiated |
|
|
151
|
+
| `ad_fill` | When ad loads successfully |
|
|
152
|
+
| `ad_impression_detailed` | When ad is shown (with fill/show rates) |
|
|
153
|
+
| `ad_not_shown` | When ad couldn't be shown |
|
|
154
|
+
|
|
155
|
+
**User properties updated:**
|
|
156
|
+
- `total_ad_requests`, `total_ad_fills`, `total_ads_shown`
|
|
157
|
+
- `ad_fill_rate`, `ad_show_rate`
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## API Changes
|
|
162
|
+
|
|
163
|
+
### AdManager - New Methods
|
|
164
|
+
|
|
165
|
+
| Method | Description |
|
|
166
|
+
|--------|-------------|
|
|
167
|
+
| `loadMultipleAdUnits(context, adUnitIds)` | Load multiple ad units into pool |
|
|
168
|
+
| `loadMultipleAdUnits(context, vararg adUnitIds)` | Vararg version |
|
|
169
|
+
| `showOrWaitForAd(activity, callback, timeout, showDialog)` | Smart splash ad showing |
|
|
170
|
+
| `getPoolSize()` | Number of ready ads in pool |
|
|
171
|
+
| `getReadyAdUnits()` | Set of ad unit IDs with ready ads |
|
|
172
|
+
| `isReady(adUnitId)` | Check if specific unit has ad ready |
|
|
173
|
+
| `clearAdPool()` | Remove all ads from pool |
|
|
174
|
+
| `getAdStats()` | Get session ad statistics |
|
|
175
|
+
| `resetAdStats()` | Reset session statistics |
|
|
176
|
+
| `preloadAd(context, adUnitId)` | Proactively preload an ad |
|
|
177
|
+
| `resetAdThrottling()` | Reset display counters and intervals |
|
|
178
|
+
| `enableAggressiveAdLoading()` | Set 5s interval for max show rate |
|
|
179
|
+
| `getLastAdShowTime()` | Timestamp of last ad show |
|
|
180
|
+
| `getTimeSinceLastAd()` | Milliseconds since last ad |
|
|
181
|
+
| `isLoading()` | Check if any ad is loading |
|
|
182
|
+
|
|
183
|
+
### AppOpenManager - New Methods
|
|
184
|
+
|
|
185
|
+
| Method | Description |
|
|
186
|
+
|--------|-------------|
|
|
187
|
+
| `prefetchNextAd(onPrefetchStarted)` | Prefetch ad before external intent |
|
|
188
|
+
| `isAdLoading()` | Check if ad is currently loading |
|
|
189
|
+
|
|
190
|
+
### AdManageKitConfig - New Properties
|
|
191
|
+
|
|
192
|
+
| Property | Type | Default | Description |
|
|
193
|
+
|----------|------|---------|-------------|
|
|
194
|
+
| `enableCrossAdUnitFallback` | Boolean | `false` | Allow native ad fallback across ad units |
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Improvements
|
|
199
|
+
|
|
200
|
+
### Modern Window APIs
|
|
201
|
+
|
|
202
|
+
Replaced deprecated `systemUiVisibility` with `WindowInsetsController` for Android 11+ compatibility:
|
|
203
|
+
|
|
204
|
+
```kotlin
|
|
205
|
+
// Old (deprecated)
|
|
206
|
+
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or ...
|
|
207
|
+
|
|
208
|
+
// New (v3.0.0)
|
|
209
|
+
WindowCompat.setDecorFitsSystemWindows(window, false)
|
|
210
|
+
WindowCompat.getInsetsController(window, decorView).apply {
|
|
211
|
+
hide(WindowInsetsCompat.Type.systemBars())
|
|
212
|
+
systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Duplicate Load Prevention
|
|
217
|
+
|
|
218
|
+
`loadInterstitialAd()` now prevents duplicate requests:
|
|
219
|
+
- Skips if ad unit is already loading
|
|
220
|
+
- Skips if ad unit already has ad in pool
|
|
221
|
+
- Logs debug events for tracking
|
|
222
|
+
|
|
223
|
+
### Improved Timeout Handling
|
|
224
|
+
|
|
225
|
+
`loadInterstitialAdForSplash()` timeout now:
|
|
226
|
+
- Resets `isAdLoading` flag to allow new requests
|
|
227
|
+
- Still saves ad if it arrives after timeout (not wasted)
|
|
228
|
+
- Prevents blocking of subsequent load calls
|
|
229
|
+
|
|
230
|
+
### Thread-Safe Ad Pool
|
|
231
|
+
|
|
232
|
+
Ad pool uses `ConcurrentHashMap` for thread safety:
|
|
233
|
+
- Safe concurrent access from multiple threads
|
|
234
|
+
- `loadingAdUnits` tracks in-flight requests
|
|
235
|
+
- No race conditions on load/show
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Migration Guide
|
|
240
|
+
|
|
241
|
+
### From 2.9.0 to 3.0.0
|
|
242
|
+
|
|
243
|
+
v3.0.0 is **fully backward compatible**. All existing code continues to work.
|
|
244
|
+
|
|
245
|
+
#### Recommended: Adopt Smart Splash Ads
|
|
246
|
+
|
|
247
|
+
Replace separate load + show calls with single `showOrWaitForAd()`:
|
|
248
|
+
|
|
249
|
+
```kotlin
|
|
250
|
+
// Before (v2.9.0) - Two-step approach
|
|
251
|
+
AdManager.getInstance().loadInterstitialAdForSplash(this, adUnitId, 10_000, object : AdManagerCallback() {
|
|
252
|
+
override fun onNextAction() {
|
|
253
|
+
if (!AdManager.getInstance().isDisplayingAd()) {
|
|
254
|
+
AdManager.getInstance().forceShowInterstitial(this@SplashActivity, callback)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
// After (v3.0.0) - Single smart call
|
|
260
|
+
AdManager.getInstance().showOrWaitForAd(
|
|
261
|
+
activity = this,
|
|
262
|
+
callback = object : AdManagerCallback() {
|
|
263
|
+
override fun onNextAction() { navigateNext() }
|
|
264
|
+
},
|
|
265
|
+
timeoutMillis = 10_000
|
|
266
|
+
)
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
#### Recommended: Use Ad Pool for Higher Show Rate
|
|
270
|
+
|
|
271
|
+
```kotlin
|
|
272
|
+
// Before (single ad unit)
|
|
273
|
+
AdManager.getInstance().loadInterstitialAd(context, "single_unit")
|
|
274
|
+
|
|
275
|
+
// After (multiple ad units for redundancy)
|
|
276
|
+
AdManager.getInstance().loadMultipleAdUnits(context, "high_ecpm", "medium_ecpm", "fallback")
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
#### Optional: Enable Cross-Ad-Unit Fallback
|
|
280
|
+
|
|
281
|
+
```kotlin
|
|
282
|
+
// In Application.onCreate()
|
|
283
|
+
AdManageKitConfig.enableCrossAdUnitFallback = true
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Installation
|
|
289
|
+
|
|
290
|
+
```groovy
|
|
291
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v3.0.0'
|
|
292
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v3.0.0'
|
|
293
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v3.0.0'
|
|
294
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-compose:v3.0.0'
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Full Changelog
|
|
300
|
+
|
|
301
|
+
### AdManager Enhancements
|
|
302
|
+
|
|
303
|
+
- Added ad pool system with `ConcurrentHashMap` for storing multiple ad units
|
|
304
|
+
- Added `loadMultipleAdUnits()` for loading multiple ad units at once
|
|
305
|
+
- Added `showOrWaitForAd()` smart method for splash screens
|
|
306
|
+
- Added duplicate load prevention (skips if already loading or in pool)
|
|
307
|
+
- Added session-level Firebase analytics (requests, fills, impressions, rates)
|
|
308
|
+
- Added `getAdStats()` and `resetAdStats()` for analytics access
|
|
309
|
+
- Added pool utility methods: `getPoolSize()`, `getReadyAdUnits()`, `clearAdPool()`
|
|
310
|
+
- Added `preloadAd()`, `resetAdThrottling()`, `enableAggressiveAdLoading()`
|
|
311
|
+
- Added `getLastAdShowTime()`, `getTimeSinceLastAd()`, `isLoading()`
|
|
312
|
+
- Improved `loadInterstitialAdForSplash()` timeout handling (resets loading flag)
|
|
313
|
+
- Updated loading dialog to use modern `WindowInsetsController` API
|
|
314
|
+
- Auto-reload now reloads the specific ad unit that was shown
|
|
315
|
+
|
|
316
|
+
### AppOpenManager Enhancements
|
|
317
|
+
|
|
318
|
+
- Added `prefetchNextAd()` for prefetching before external intents
|
|
319
|
+
- Added `isAdLoading()` to check loading state
|
|
320
|
+
- Changed `currentActivityRef: WeakReference<Activity>` to direct reference for reliability
|
|
321
|
+
- Updated welcome dialog to use modern `WindowInsetsController` API
|
|
322
|
+
|
|
323
|
+
### NativeAdManager Enhancements
|
|
324
|
+
|
|
325
|
+
- Added cross-ad-unit fallback when `enableCrossAdUnitFallback` is true
|
|
326
|
+
- Added documentation for destructive read pattern (ad removed from cache on retrieve)
|
|
327
|
+
- Improved fallback priority: same base unit variants → cross ad unit
|
|
328
|
+
|
|
329
|
+
### NativeTemplateView Enhancements
|
|
330
|
+
|
|
331
|
+
- Added `MEDIUM_HORIZONTAL` template: 55% media (left) / 45% content (right) horizontal split
|
|
332
|
+
- Total templates now: 24 (18 standard + 6 video)
|
|
333
|
+
|
|
334
|
+
### Config Enhancements
|
|
335
|
+
|
|
336
|
+
- Added `enableCrossAdUnitFallback` property to `AdManageKitConfig`
|
|
337
|
+
|
|
338
|
+
### Technical Improvements
|
|
339
|
+
|
|
340
|
+
- Replaced deprecated `systemUiVisibility` with `WindowInsetsController` throughout
|
|
341
|
+
- Added `WindowCompat.setDecorFitsSystemWindows()` for edge-to-edge display
|
|
342
|
+
- Thread-safe ad pool with `ConcurrentHashMap` and `ConcurrentHashMap.newKeySet()`
|
|
343
|
+
- Improved logging with pool size and ad unit tracking
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Release Notes - v3.1.0
|
|
2
|
+
|
|
3
|
+
## Highlights
|
|
4
|
+
|
|
5
|
+
- **FRESH_WITH_CACHE_FALLBACK Fix**: Successfully loaded ads are now properly cached for future fallback scenarios
|
|
6
|
+
- **New Template**: `MEDIUM_HORIZONTAL` - 55/45 media-content horizontal split layout
|
|
7
|
+
- **Test Activity**: Video ad toggle and updated template documentation
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## New Features
|
|
12
|
+
|
|
13
|
+
### FRESH_WITH_CACHE_FALLBACK Strategy - Now Caches Successfully Loaded Ads
|
|
14
|
+
|
|
15
|
+
The `FRESH_WITH_CACHE_FALLBACK` strategy now works as documented. Successfully loaded fresh ads are automatically cached for future fallback use.
|
|
16
|
+
|
|
17
|
+
**Before v3.1.0:** Fresh ads were displayed but NOT cached, making fallback ineffective over time.
|
|
18
|
+
|
|
19
|
+
**After v3.1.0:** Fresh ads are displayed AND cached, building up the cache for better fallback availability.
|
|
20
|
+
|
|
21
|
+
```kotlin
|
|
22
|
+
// Perfect for RecyclerView scenarios
|
|
23
|
+
AdManageKitConfig.nativeLoadingStrategy = AdLoadingStrategy.FRESH_WITH_CACHE_FALLBACK
|
|
24
|
+
|
|
25
|
+
// How it works now:
|
|
26
|
+
// 1. Try to load fresh ad from network
|
|
27
|
+
// 2. If SUCCESS → Display ad AND cache it for future fallback
|
|
28
|
+
// 3. If FAIL → Fall back to cached ad (if available)
|
|
29
|
+
// 4. Result: Over time, cache builds up with successful loads
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### New Native Template: MEDIUM_HORIZONTAL
|
|
33
|
+
|
|
34
|
+
A new horizontal split layout with 55% media on the left and 45% content on the right.
|
|
35
|
+
|
|
36
|
+
```xml
|
|
37
|
+
<com.i2hammad.admanagekit.admob.NativeTemplateView
|
|
38
|
+
android:layout_width="match_parent"
|
|
39
|
+
android:layout_height="wrap_content"
|
|
40
|
+
app:adTemplate="medium_horizontal" />
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```kotlin
|
|
44
|
+
nativeTemplateView.setTemplate(NativeAdTemplate.MEDIUM_HORIZONTAL)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Layout Structure:**
|
|
48
|
+
- Left side: MediaView (55% width, 140dp height)
|
|
49
|
+
- Right side: Ad badge, app icon, headline, body, CTA button (45% width)
|
|
50
|
+
|
|
51
|
+
**Total Templates:** 24 (18 standard + 6 video)
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Improvements
|
|
56
|
+
|
|
57
|
+
### NativeTemplateTestActivity
|
|
58
|
+
|
|
59
|
+
- **Video Ad Toggle**: Switch between standard native ad (`2247696110`) and video native ad (`1044960115`) test units
|
|
60
|
+
- **Updated Notes**: Reflects all 24 available templates with accurate counts
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Full Changelog
|
|
65
|
+
|
|
66
|
+
### NativeTemplateView Enhancements
|
|
67
|
+
|
|
68
|
+
- Added `MEDIUM_HORIZONTAL` template with horizontal 55/45 split layout
|
|
69
|
+
- Added `loadingStrategy` parameter to internal `loadNewAdInternal()` method
|
|
70
|
+
- Fresh ads are now cached when using `FRESH_WITH_CACHE_FALLBACK` strategy
|
|
71
|
+
|
|
72
|
+
### NativeAdIntegrationManager
|
|
73
|
+
|
|
74
|
+
- Updated comment in `createFreshWithCacheFallbackCallback` to accurately describe caching behavior
|
|
75
|
+
|
|
76
|
+
### Test Activity
|
|
77
|
+
|
|
78
|
+
- Added `SwitchMaterial` for toggling between standard and video ad units
|
|
79
|
+
- Added `tvAdUnitInfo` to display current ad unit type
|
|
80
|
+
- Updated template count from 17 to 24 in layout notes
|
|
81
|
+
|
|
82
|
+
### Attrs
|
|
83
|
+
|
|
84
|
+
- Added `medium_horizontal` enum value (16)
|
|
85
|
+
- Shifted `spotlight` and video template values accordingly
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Migration Guide
|
|
90
|
+
|
|
91
|
+
Version 3.1.0 is **fully backward compatible**. No migration required.
|
|
92
|
+
|
|
93
|
+
### Recommended: Use FRESH_WITH_CACHE_FALLBACK for RecyclerView
|
|
94
|
+
|
|
95
|
+
If you're showing native ads in a RecyclerView, consider using `FRESH_WITH_CACHE_FALLBACK`:
|
|
96
|
+
|
|
97
|
+
```kotlin
|
|
98
|
+
// Global configuration
|
|
99
|
+
AdManageKitConfig.nativeLoadingStrategy = AdLoadingStrategy.FRESH_WITH_CACHE_FALLBACK
|
|
100
|
+
|
|
101
|
+
// Or per-call
|
|
102
|
+
nativeTemplateView.loadNativeAd(
|
|
103
|
+
activity = this,
|
|
104
|
+
adUnitId = "ca-app-pub-xxx/yyy",
|
|
105
|
+
adCallback = callback,
|
|
106
|
+
loadingStrategy = AdLoadingStrategy.FRESH_WITH_CACHE_FALLBACK
|
|
107
|
+
)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Benefits:**
|
|
111
|
+
- Each item binding tries to get a fresh ad (better revenue)
|
|
112
|
+
- If network fails, cached ad appears immediately (no empty space)
|
|
113
|
+
- Successfully loaded ads build up the cache over time
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Dependencies
|
|
118
|
+
|
|
119
|
+
No dependency changes from v3.0.0.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Bug Fixes
|
|
124
|
+
|
|
125
|
+
- **Fixed**: `FRESH_WITH_CACHE_FALLBACK` strategy not caching successfully loaded ads
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Known Issues
|
|
130
|
+
|
|
131
|
+
None.
|