init static method
Future<AdsService>
init({
- required AdsAdUnitIds adUnitIds,
- AdsRemoteConfigOptions? remoteConfig,
- int interstitialAfter = 3,
- bool isProUser()?,
- AdsConsentOptions? consent,
- AdsPolicyOptions? policy,
- bool? bannerEnabled,
- bool? interstitialEnabled,
- bool? nativeEnabled,
- bool? appOpenEnabled,
- bool? rewardedEnabled,
- bool? directInterstitialEnabled,
- bool adsEnabled = true,
- int maxRetryAttempts = 2,
- Duration retryBaseDelay = const Duration(seconds: 10),
- bool preloadEnabled = true,
- Duration connectivityRecheckInterval = const Duration(minutes: 3),
Initialize the package once.
Calling this method more than once is safe; subsequent calls are ignored by AdsService. Initialization errors are logged and do not crash the host app, because advertising should never prevent the app from opening.
Implementation
static Future<AdsService> init({
required AdsAdUnitIds adUnitIds,
AdsRemoteConfigOptions? remoteConfig,
int interstitialAfter = 3,
bool Function()? isProUser,
AdsConsentOptions? consent,
AdsPolicyOptions? policy,
bool? bannerEnabled,
bool? interstitialEnabled,
bool? nativeEnabled,
bool? appOpenEnabled,
bool? rewardedEnabled,
bool? directInterstitialEnabled,
bool adsEnabled = true,
int maxRetryAttempts = 2,
Duration retryBaseDelay = const Duration(seconds: 10),
bool preloadEnabled = true,
Duration connectivityRecheckInterval = const Duration(minutes: 3),
}) async {
if (AdsService.isInitialized) {
dPrint('🔁 AdsBootstrap: already initialized, skipping');
return AdsService.instance;
}
final options = remoteConfig ?? const AdsRemoteConfigOptions.disabled();
_consentManager = null;
AdsConsentManager? consentManager;
final consentOptions = resolveConsentOptions(consent: consent);
final useConsent = consent != null || !kDebugMode;
if (useConsent) {
consentManager = AdsConsentManager();
_consentManager = consentManager;
final canRequestAds = await consentManager.requestConsent(consentOptions);
dPrint('🛡️ AdsBootstrap: consent gate allows ads = $canRequestAds');
}
if (policy != null) {
try {
await MobileAds.instance.updateRequestConfiguration(
policy.toRequestConfiguration(),
);
} catch (error) {
// Restriction configuration must not make the host app fail to open.
// The host can observe this in its own logs and should verify native
// setup if it occurs.
dPrint('⚠️ AdsBootstrap: request policy could not be applied: $error');
}
}
final config = adUnitIds.toConfig(
bannerEnabled: bannerEnabled,
interstitialEnabled: interstitialEnabled,
nativeEnabled: nativeEnabled,
appOpenEnabled: appOpenEnabled,
rewardedEnabled: rewardedEnabled,
directInterstitialEnabled: directInterstitialEnabled,
adsEnabled: adsEnabled,
interstitialAfter: interstitialAfter,
maxRetryAttempts: maxRetryAttempts,
retryBaseDelay: retryBaseDelay,
preloadEnabled: preloadEnabled,
connectivityRecheckInterval: connectivityRecheckInterval,
);
dPrint('🚀 AdsBootstrap: starting with ${config.availableAdTypes}');
final AdsKeyProvider provider;
if (options.enabled) {
provider = RemoteConfigAdsKeyProvider(
fallback: config,
customKeys: options.keys,
onConfigFetched: options.onFetched,
fetchTimeout: options.fetchTimeout,
minimumFetchInterval: options.minimumFetchInterval,
);
dPrint('🔥 AdsBootstrap: Remote Config enabled');
} else {
provider = DirectAdsKeyProvider(config);
dPrint('📦 AdsBootstrap: using supplied IDs without Remote Config');
}
try {
final service = await AdsService.initialize(
keyProvider: provider,
isProUser: isProUser,
consentChecker: consentManager?.canRequestAds,
);
dPrint('✅ AdsBootstrap: initialization complete');
service.dPrintDebug();
return service;
} catch (error, stackTrace) {
dPrint('❌ AdsBootstrap: initialization failed: $error');
dPrint('$stackTrace');
// The service's safe pre-init getters keep the host app usable.
return AdsService.instance;
}
}