Example optimisation code
Flow diagram

Disable Back-to-back Ad Loading
It's important that you disable back to back ad loading in MAX when using multi ad unit set up before initializing MAX SDK:
private readonly string[] _adUnits = new string[] {
#if UNITY_IOS
// interstitials // Replace with your ad unit ids
"6d318f954e2630a8", "37146915dc4c7740", "e5dc3548d4a0913f",
// rewarded // Replace with your ad unit ids
"918acf84edf9c034", "37163b1a07c4aaa0", "e0b0d20088d60ec5"
#else // UNITY_ANDROID
// interstitials // Replace with your ad unit ids
"7267e7f4187b95b2", "00b665eda2658439", "87f1b4837da231e5",
// rewarded // Replace with your ad unit ids
"72458470d47ee781", "5305c7824f0b5e0a", "a4b93fe91b278c75"
#endif
};
MaxSdk.SetExtraParameter("disable_b2b_ad_unit_ids", string.Join(",", _adUnits));
MaxSdk.InitializeSdk();
let adUnits = [
// interstitials
"6d318f954e2630a8", "37146915dc4c7740", "e5dc3548d4a0913f",
// rewarded
"918acf84edf9c034", "37163b1a07c4aaa0", "e0b0d20088d60ec5"
]
let max = ALSdk.shared()
max.settings.setExtraParameterForKey("disable_b2b_ad_unit_ids", value: adUnits.joined(separator: ","))
max.settings.isVerboseLoggingEnabled = true
let initConfig = ALSdkInitializationConfiguration(sdkKey: "key") { builder in
builder.mediationProvider = ALMediationProviderMAX
}
max.initialize(with: initConfig) { sdkConfig in
}
ALSdkInitializationConfiguration *initConfig = [ALSdkInitializationConfiguration configurationWithSdkKey: @"key" builderBlock:^(ALSdkInitializationConfigurationBuilder *builder) {
builder.mediationProvider = ALMediationProviderMAX;
}];
ALSdkSettings *settings = [ALSdk shared].settings;
NSArray *adUnits = @[
// interstitials
@"6d318f954e2630a8", @"37146915dc4c7740", @"e5dc3548d4a0913f",
// rewarded
@"918acf84edf9c034", @"37163b1a07c4aaa0", @"e0b0d20088d60ec5"
];
[settings setExtraParameterForKey: @"disable_b2b_ad_unit_ids" value: [adUnits componentsJoinedByString:@","]];
[[ALSdk shared] initializeWithConfiguration: initConfig completionHandler:^(ALSdkConfiguration *sdkConfig) {
}];
String[] adUnits = new String[]{
// interstitials
"7267e7f4187b95b2", "00b665eda2658439", "87f1b4837da231e5",
// rewarded
"72458470d47ee781", "5305c7824f0b5e0a", "a4b93fe91b278c75"
};
AppLovinSdk sdk = AppLovinSdk.getInstance(this);
sdk.getSettings().setExtraParameter("disable_b2b_ad_unit_ids", String.join(",", adUnits));
AppLovinSdkInitializationConfiguration initConfig = AppLovinSdkInitializationConfiguration.builder( "key" )
.setMediationProvider( AppLovinMediationProvider.MAX )
.build();
sdk.initialize( initConfig, new AppLovinSdk.SdkInitializationListener() {
@Override
public void onSdkInitialized(final AppLovinSdkConfiguration sdkConfig) {
AppLovinSdk.getInstance(MainActivity.this).getSettings().setVerboseLogging(true);
}
});
List<String> adUnits = Platform.isAndroid ?
["0822634ec9c39d78", "084edff9524b52ec", "3d7ef05a78cf8615", "c0c516310b8c7c04" ] :
["5e11b1838778c517", "fbd50dc3d655933c", "ad9b024164e61c00", "c068edf12c4282a6" ];
AppLovinMAX.setExtraParameter("disable_b2b_ad_unit_ids", adUnits.join(","));
Find the example optimisation code
private void GetInsightsAndLoad()
{
NeftaAdapterEvents.GetInsights(Insights.Rewarded, OnInsights, TimeoutInSeconds);
}
private void OnInsights(Insights insights)
{
_selectedAdUnitId = DefaultAdUnitId;
_usedInsight = insights._rewarded;
if (_usedInsight != null && _usedInsight._adUnit != null)
{
_selectedAdUnitId = _usedInsight._adUnit;
}
SetStatus($"Loading {_selectedAdUnitId} insights: {_usedInsight}");
MaxSdk.SetRewardedAdExtraParameter(_selectedAdUnitId, "disable_auto_retries", "true");
MaxSdk.LoadRewardedAd(_selectedAdUnitId);
}
private void OnAdFailedEvent(string adUnitId, MaxSdkBase.ErrorInfo errorInfo)
{
NeftaAdapterEvents.OnExternalMediationRequestFailed(NeftaAdapterEvents.AdType.Rewarded, _usedInsight, adUnitId, errorInfo);
SetStatus($"Load failed {adUnitId}: {errorInfo}");
_consecutiveAdFails++;
StartCoroutine(RetryLoadWithDelay());
}
private IEnumerator RetryLoadWithDelay()
{
// As per MAX recommendations, retry with exponentially higher delays up to 64s
// In case you would like to customize fill rate / revenue please contact our customer support
yield return new WaitForSeconds(new [] { 0, 2, 4, 8, 16, 32, 64 }[Math.Min(_consecutiveAdFails, 6)]);
GetInsightsAndLoad();
}
private void OnAdLoadedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
{
NeftaAdapterEvents.OnExternalMediationRequestLoaded(NeftaAdapterEvents.AdType.Rewarded, _usedInsight, adInfo);
SetStatus($"Loaded {adUnitId} at: {adInfo.Revenue}");
_consecutiveAdFails = 0;
_show.interactable = true;
}
private func GetInsightsAndLoad() {
NeftaPlugin._instance.GetInsights(Insights.Rewarded, callback: Load, timeout: TimeoutInSeconds)
}
private func Load(insights: Insights) {
var selectedAdUnitId = DefaultAdUnitId
_usedInsight = insights._rewarded
if let usedInsight = _usedInsight, let recommendedAdUnit = usedInsight._adUnit {
selectedAdUnitId = recommendedAdUnit
}
let adUnitToLoad = selectedAdUnitId
Log("Loading \(selectedAdUnitId) insights: \(String(describing: _usedInsight))")
_rewarded = MARewardedAd.shared(withAdUnitIdentifier: adUnitToLoad)
_rewarded!.delegate = self
_rewarded!.setExtraParameterForKey("disable_auto_retries", value: "true")
_rewarded!.load()
}
func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
ALNeftaMediationAdapter.onExternalMediationRequestFail(.rewarded, adUnitIdentifier: adUnitIdentifier, usedInsight: _usedInsight, error: error)
Log("didFailToLoadAd \(adUnitIdentifier): \(error)")
_consecutiveAdFails += 1
// As per MAX recommendations, retry with exponentially higher delays up to 64s
// In case you would like to customize fill rate / revenue please contact our customer support
let delayInSeconds = [0, 2, 4, 8, 16, 32, 64][min(_consecutiveAdFails, 6)]
DispatchQueue.main.asyncAfter(deadline: .now() + Double(delayInSeconds)) {
self.GetInsightsAndLoad()
}
}
func didLoad(_ ad: MAAd) {
ALNeftaMediationAdapter.onExternalMediationRequestLoad(.rewarded, ad: ad, usedInsight: _usedInsight)
Log("didLoad \(ad) at: \(ad.revenue)")
_consecutiveAdFails = 0
_showButton.isEnabled = true
}
- (void)GetInsightsAndLoad {
[NeftaPlugin._instance GetInsights: Insights.Interstitial callback: ^(Insights * insights) {
[self Load: insights];
} timeout: TimeoutInSeconds];
}
-(void)Load:(Insights *) insights {
NSString *selectedAdUnitId = DefaultAdUnitId;
_usedInsight = insights._interstitial;
if (_usedInsight != nil && _usedInsight._adUnit != nil) {
selectedAdUnitId = _usedInsight._adUnit;
}
NSLog(@"Loading %@ insights %@", selectedAdUnitId, _usedInsight);
_interstitial = [[MAInterstitialAd alloc] initWithAdUnitIdentifier: selectedAdUnitId];
_interstitial.delegate = self;
[_interstitial setExtraParameterForKey: @"disable_auto_retries" value: @"true"];
[_interstitial loadAd];
}
- (void)didFailToLoadAdForAdUnitIdentifier:(NSString *)adUnitIdentifier withError:(MAError *)error {
[ALNeftaMediationAdapter OnExternalMediationRequestFail: AdTypeInterstitial adUnitIdentifier: adUnitIdentifier usedInsight: _usedInsight error: error];
NSLog(@"didFailToLoadAdForAdUnitIdentifier %@: %@", adUnitIdentifier, error);
_consecutiveAdFails++;
// As per MAX recommendations, retry with exponentially higher delays up to 64s
// In case you would like to customize fill rate / revenue please contact our customer support
int delayInSeconds = (int[]){ 0, 2, 4, 8, 16, 32, 64 }[MIN(_consecutiveAdFails, 6)];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self GetInsightsAndLoad];
});
}
- (void)didLoadAd:(MAAd *)ad {
[ALNeftaMediationAdapter OnExternalMediationRequestLoad: AdTypeInterstitial ad: ad usedInsight: _usedInsight];
NSLog(@"didLoadAd %@: %f", ad, ad.revenue);
_consecutiveAdFails = 0;
_showButton.enabled = true;
}
private void GetInsightsAndLoad() {
NeftaPlugin._instance.GetInsights(Insights.REWARDED, this::Load, TimeoutInSeconds);
}
private void Load(Insights insights) {
String selectedAdUnitId = DefaultAdUnitId;
_usedInsight = insights._rewarded;
if (_usedInsight != null && _usedInsight._adUnit != null) {
selectedAdUnitId = _usedInsight._adUnit;
}
Log("Loading "+ selectedAdUnitId +" insights: "+ _usedInsight);
_rewardedAd = MaxRewardedAd.getInstance(selectedAdUnitId);
_rewardedAd.setListener(RewardedWrapper.this);
_rewardedAd.setRevenueListener(RewardedWrapper.this);
_rewardedAd.setExpirationListener(RewardedWrapper.this);
_rewardedAd.setExtraParameter("disable_auto_retries", "true");
_rewardedAd.loadAd();
}
@Override
public void onAdLoadFailed(@NonNull String adUnitId, @NonNull MaxError maxError) {
NeftaMediationAdapter.OnExternalMediationRequestFailed(NeftaMediationAdapter.AdType.Rewarded, adUnitId, _usedInsight, maxError);
Log("onAdLoadFailed "+ adUnitId + ": "+ maxError.getMessage());
_consecutiveAdFails++;
// As per MAX recommendations, retry with exponentially higher delays up to 64s
// In case you would like to customize fill rate / revenue please contact our customer support
int delayInSeconds = new int[] { 0, 2, 4, 8, 16, 32, 64 } [Math.min(_consecutiveAdFails, 6)];
_handler.postDelayed(this::GetInsightsAndLoad, delayInSeconds * 1000L);
}
@Override
public void onAdLoaded(@NonNull MaxAd ad) {
NeftaMediationAdapter.OnExternalMediationRequestLoaded(NeftaMediationAdapter.AdType.Rewarded, ad, _usedInsight);
Log("onAdLoaded "+ ad.getAdUnitId() +": "+ ad.getRevenue());
_consecutiveAdFails = 0;
_showButton.setEnabled(true);
}
void initializeRewarded() {
AppLovinMAX.setRewardedAdListener(RewardedAdListener(
onAdLoadedCallback: (ad) {
Nefta.onExternalMediationRequestLoaded(AdType.Rewarded, _rewardedInsight, ad);
log("Rewarded ad loaded from ${ad.networkName}");
_rewardedRetryAttempt = 0;
},
onAdLoadFailedCallback: (adUnitId, error) {
Nefta.onExternalMediationRequestFailed(AdType.Rewarded, _rewardedInsight, adUnitId, error);
_rewardedRetryAttempt = _rewardedRetryAttempt + 1;
if (_rewardedRetryAttempt > 6) return;
int retryDelay = pow(2, min(6, _rewardedRetryAttempt)).toInt();
log("Rewarded ad failed to load with code ${error.code.toString()} - retrying in {retryDelay.toString()}s");
Future.delayed(Duration(milliseconds: retryDelay * 1000), () {
getRewardedInsightAndLoad();
});
},
onAdRevenuePaidCallback: (ad) {
Nefta.onExternalMediationImpression(ad);
log("onAdRevenuePaidCallback: ${ad.revenue}");
},
// ..
));
}
void getRewardedInsightAndLoad() {
Nefta.getInsights(Insights.REWARDED, loadRewarded, 5);
}
void loadRewarded(Insights insights) {
_rewardedAdUnitId = _defaultRewardedAdUnitId;
_rewardedInsight = insights.rewarded;
if (_rewardedInsight != null) {
if (_rewardedInsight!.adUnit != null && _rewardedInsight!.adUnit!.isNotEmpty) {
_rewardedAdUnitId = _rewardedInsight!.adUnit!;
}
}
AppLovinMAX.setRewardedAdExtraParameter(_rewardedAdUnitId, "disable_auto_retries", "true");
AppLovinMAX.loadRewardedAd(_rewardedAdUnitId!);
}
Updated 7 days ago