AppLovin / AppLovin-MAX-SDK-Android

Other
210 stars 95 forks source link

App crashes with "Failed to load new ad - this instance is already destroyed for ad unit ID: <AdUnitId>" #583

Closed NorbertRudzki closed 7 months ago

NorbertRudzki commented 7 months ago

MAX SDK Version

12.0.0

Device/Platform Info

Android

Current Behavior

After sdk update from version 11.11.3 to version 12.0.0, the application started crashing on production in 60 users. We load ads from Amazon SDK according to the documentation ( https://dash.applovin.com/documentation/mediation/android/mediation-adapters?network=AMAZON_MARKETPLACE_NETWORK#load-a-banner-ad-from-amazon%E2%80%99s-sdk ) and get crashes on adView?.loadAd() method called in DTBAdCallback with both onSuccess, onFailure

`Fatal Exception: java.lang.IllegalStateException Failed to load new ad - this instance is already destroyed for ad unit ID: AdUnitId com.applovin.impl.mediation.ads.MaxAdViewImpl.a (SourceFile:252) com.applovin.impl.mediation.ads.MaxAdViewImpl.loadAd (SourceFile:240) com.applovin.impl.mediation.ads.MaxAdViewImpl.loadAd (SourceFile:197) com.applovin.mediation.ads.MaxAdView.loadAd (SourceFile:151) com.listonic.ad.providers.applovin.g$b.onSuccess (ApplovinBannerView.kt:4) com.listonic.ad.providers.applovin.d$c.onSuccess (AmazonApplovinHelper.kt:1) com.amazon.device.ads.DTBAdRequest.executeCallback (DTBAdRequest.java:974) com.amazon.device.ads.DTBAdRequest.lambda$triggerCallBack$2 (DTBAdRequest.java) android.os.Handler.handleCallback (Handler.java:942)

com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1067)`

as well as on the later onAdRefresh:

`Caused by java.lang.IllegalStateException Failed to load new ad - this instance is already destroyed for ad unit ID: AdUnitId com.applovin.impl.mediation.ads.MaxAdViewImpl.a (SourceFile:252) com.applovin.impl.mediation.ads.MaxAdViewImpl.loadAd (SourceFile:240) com.applovin.impl.mediation.ads.MaxAdViewImpl.onAdRefresh (SourceFile:649) com.applovin.impl.sdk.e.AA (SourceFile:297) com.applovin.impl.sdk.e.onReceive (SourceFile:228) com.applovin.impl.sdk.AppLovinBroadcastManager.sendBroadcastSync (SourceFile:232) com.applovin.impl.sdk.SessionTracker.Ft (SourceFile:219) com.applovin.impl.sdk.SessionTracker.AA (SourceFile:159) com.applovin.impl.sdk.SessionTracker.a com.applovin.impl.sdk.SessionTracker$1.onActivityResumed (SourceFile:69) android.app.Application.dispatchActivityResumed (Application.java:450)

com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1067)`

Expected Behavior

The app does not need to crash.

How to Reproduce

Update sdk to 12.0.0 and load banner Ad from Amazon’s SDK

Additional Info

No response

AviNLeung commented 7 months ago

Hi,

Thanks for bringing this up. It looks like you might be trying to load an adView instance that has already been destroyed. Can you make sure adView.destroy() is not called before adView.loadAd() and let us know if that resolves the issue?

NorbertRudzki commented 7 months ago

We call adView.destroy() on lifecycle activity onPause ( to avoid loading ads in the background), and onResume we create a new instance of MaxAdView and load the ad in it using DTBAdCallback. We have had this implementation unchanged for many months in previous versions, and only on 12.0.0 it began to crash (about 2.5% of all users). Is there any way to check if the adView is destroyed and we could check that directly before calling adView.loadAd()? Perhaps DTBAdCallback is not interrupted and DTBAdResponse comes already after lifecycle onPause

AviNLeung commented 7 months ago

In sdk 12.0.0 we started notifying publishers when they try to load ads that have been destroyed, because it is a missed opportunity to display an ad.

I cannot give you specific guidance without seeing your implementation. If you want to keep your current configuration, my suggestion would be to set a flag, every time you destroy and or create the adView, and use that to determine if the adView has been destroyed before loading it.

NorbertRudzki commented 7 months ago

Ok, it seems that we had this bug before, and only since sdk 12.0.0 you inform publishers about destroyed adViews it ends up with a crash instead of a missed ad. We will correct our implementation, thanks for the clarification.

inidamleader commented 7 months ago

It seems that either: 1- MaxAd Banner view use pattern singleton for creation which return the same instance after configuration change. 2- Or even after calling destroy on a MaxAd, this one keep refreshing and loading new content while it is already destroyed. Using a flag to check if destroy is called does not work because this is an intern error related to refreshing.

I think that there is a workaound that reduce considerably the number of crashes: It consists of stopping the auto refreshing just before the destruction:

    override fun destroy() {
        maxAdView.stopAutoRefresh()
        maxAdView.destroy()
        super.destroy()
    }
AviNLeung commented 7 months ago

Thank you for the information. I will look into fixing any internal errors related to this.

Just so you know, our SDK is configured such that this crash will only be thrown in debug builds, which means the crash will not be affecting any traffic going forward. I hope that gives some peace of mind in the meantime.

inidamleader commented 7 months ago

@AviNLeung No, this crash is affecting my app on production. Please see the attached image file:

Screenshot 2023-11-27 at 10-03-43 OvTracker - com applovin impl mediation ads MaxAdViewImpl a - Firebase console

AviNLeung commented 7 months ago

We disabled the crash from happening in release builds yesterday, so moving forward it should not be affecting traffic. Let me know if you see otherwise.

AviNLeung commented 6 months ago

FYI, we released a fix for this issue today in our newest SDK version 12.1.0(https://support.applovin.com/hc/en-us/articles/13887934767117-Changelog).