AppLovin / AppLovin-MAX-SDK-Android

Other
232 stars 104 forks source link

MAX Mediation MediationAdapterBase.destroy() is getting invoke in background thread. #728

Closed pm-vishal-chougule closed 1 week ago

pm-vishal-chougule commented 1 month ago

MAX SDK Version

12.6.1, 13.0.0

Device/Platform Info

Android

Crashes/ANRs per Day

10

Percentage of Users Affected

NA

First Occurrence of Crash/ANR

10 Oct 2024 Though the stacktrace is NPE and does not show any path of the AppLovinMAX Adapter, but the AppLovinMAX invokes destroy() callback in background and invalidates the internal resources of OpenWrap SDK and that's causing NPE.

Exception and Stack Trace

Caused by java.lang.NullPointerException: Attempt to invoke interface method 'void com.pubmatic.sdk.common.viewability.POBHTMLMeasurementProvider.signalAdEvent(com.pubmatic.sdk.common.viewability.POBHTMLMeasurementProvider$POBHTMLAdEventType)' on a null object reference at com.pubmatic.sdk.webrendering.mraid.POBMraidRenderer.h(POBMraidRenderer.java:4) at com.pubmatic.sdk.webrendering.mraid.POBMraidRenderer.onViewRendered(POBMraidRenderer.java:15) at com.pubmatic.sdk.webrendering.ui.POBHTMLRenderer.onPageFinished(POBHTMLRenderer.java:3) at com.pubmatic.sdk.webrendering.ui.POBHTMLViewClient.onPageFinished(POBHTMLViewClient.java:4) at m65.b(chromium-Monochrome.aab-stable-604519420:12) at Ay.handleMessage(chromium-Monochrome.aab-stable-604519420:277) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6823) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1557) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)

How to Reproduce

Steps:

  1. Create MaxAdView with placement details
  2. Load MaxAdView by calling loadAd(); API
  3. Destroy MaxAdView by calling destroy() API. with the above steps, you see MediationAdapterBase.destroy() invokes on the background thread.

Reproducible in the demo app?

No

Additional Info

Adapter implementation for View classes expects to be invoked on the Main thread. I can see a similar issue reported, reference: https://github.com/AppLovin/AppLovin-MAX-SDK-Android/issues/723

NanaAmoah commented 1 month ago

Hi @pm-vishal-chougule, we're looking into this and will keep you updated

pm-vishal-chougule commented 1 month ago

Hi @NanaAmoah, Thanks for the update, Do you have any timelines for the fix? Thanks.

NanaAmoah commented 1 month ago

Hi @pm-vishal-chougule, I have not been able to reproduce the issue on my end after testing by following the reproduction steps you shared. Could you clarify/share on the following to help with our investigation:

For the fix referenced here, we're actively working on it and will let you know when we have more information on timelines.

pm-vishal-chougule commented 1 month ago

Hi @NanaAmoah, Thanks for the updates.

The screenshot below is taken for AppLovinMAX SDK v12.6.0, you can see Lopper is available and its type is Main and in the thread dump the current thread daemon is false

Screenshot 2024-10-24 at 3 10 10 PM

The screenshot below is with AppLovinMAX SDK v13.0.0, you can see Looper is null(Main thread always associates with Main Looper) and in the thread dump the current thread daemon is true.

Screenshot 2024-10-24 at 3 10 27 PM

From the above screenshots it looks like MediationAdapterBase.destroy() method is getting invoked on non-main thread from AppLovinMAX SDK v12.6.1 onwards, which is causing intermittent crashes in OpenWrap SDK.

Thanks.

pm-vishal-chougule commented 1 month ago

Hi @NanaAmoah,

I have verified this issue for SDK Bidder integration through the PubMaticMediationAdapter and AppLovinMAX SDK v13.0.0, I see the destroy() method is being invoked on non-main thread. The screenshot below will help you understand. The thread in which destroy() is invoked does not have a looper associated with it.

Screenshot 2024-10-24 at 7 28 52 PM

Thanks.

NanaAmoah commented 1 month ago

Hi @pm-vishal-chougule, thanks for the additional information. We are aware of the issue of destroy() being called on a non-main thread. It is the same issue referenced in the ticket above which we are working on fixing.

To clarify, what I'm not able to reproduce is the NPE for which you shared the stack trace, i.e Caused by java.lang.NullPointerException: Attempt to invoke interface method 'void com.pubmatic.sdk.common.viewability.POBHTMLMeasurementProvider.signalAdEvent(com.pubmatic.sdk.common.viewability.POBHTMLMeasurementProvider$POBHTMLAdEventType)' on a null object reference.

I will notify you when we release the fix to call destroy on the main thread.

pm-vishal-chougule commented 1 month ago

@NanaAmoah , Thanks for the confirmation. Please let me know the release updates. Thanks.

pm-vishal-chougule commented 1 week ago

Hi @NanaAmoah, We have observed a similar issue while showing interstitial ads in the custom mediation workflow. The below stacktrace suggests that AppLovinMAX SDK is invoking custom adapter APIs like loadInterstitialAd(), showInterstitialAd(), and similar ad format APIs on the background thread and that causes a crash.

Caused by java.lang.IllegalStateException: Calling View methods on another thread than the UI thread.
       at com.android.webview.chromium.WebViewChromium.a(chromium-TrichromeWebViewGoogle6432.aab-stable-672310733:12)
       at com.android.webview.chromium.WebViewChromium.setLayoutParams(chromium-TrichromeWebViewGoogle6432.aab-stable-672310733:7)
       at android.webkit.WebView.setLayoutParams(WebView.java:2663)
       at android.view.ViewGroup.addViewInner(ViewGroup.java:5576)
       at android.view.ViewGroup.addView(ViewGroup.java:5352)
       at android.view.ViewGroup.addView(ViewGroup.java:5324)
       at com.pubmatic.sdk.webrendering.ui.POBMraidViewContainer.<init>(POBMraidViewContainer.java:12)
       at com.pubmatic.sdk.openwrap.core.interstitial.POBInterstitialRenderer.a(POBInterstitialRenderer.java:74)
       at com.pubmatic.sdk.openwrap.core.interstitial.POBInterstitialRenderer.a(POBInterstitialRenderer.java:6)
       at com.pubmatic.sdk.openwrap.core.interstitial.POBInterstitialRenderer.show(POBInterstitialRenderer.java:1)
       at com.pubmatic.sdk.openwrap.interstitial.POBInterstitial.show(POBInterstitial.java:6)
       at com.applovin.mediation.openwrap.ALPubMaticOpenWrapMediationAdapter.showInterstitialAd(SourceFile:2)
       at com.applovin.impl.mediation.g.d(SourceFile:6)
       at com.applovin.impl.mediation.g.$r8$lambda$cnLLdwQw3aRSE-N2PopbrZ4ouGs()
       at com.applovin.impl.mediation.g$$ExternalSyntheticLambda10.run(:4)
       at com.applovin.impl.mediation.g.a(SourceFile:5796)
       at com.applovin.impl.mediation.g.$r8$lambda$-eXdiRjHa6OZjx0B4_h0IJnWzUI()
       at com.applovin.impl.mediation.g$$ExternalSyntheticLambda15.run(:4)
       at com.applovin.impl.mediation.g.a(SourceFile:5869)
       at com.applovin.impl.mediation.g.$r8$lambda$8klZvVFxEvbeYtUWLTk7pAlNUX4()
       at com.applovin.impl.mediation.g$$ExternalSyntheticLambda14.run(:6)
       at com.applovin.impl.jn.run(SourceFile:46)
       at com.applovin.impl.tm$d.run(SourceFile:24)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:487)
       at java.util.concurrent.FutureTask.run(FutureTask.java:264)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:307)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
       at java.lang.Thread.run(Thread.java:1012)

We confirm these APIs are getting invoked on the Background Thread on v12.5.0, 12.6.0, and 13.0.1 as well.

On the contrary, for the SDK bidding flow AppLovinMAX SDK v 13.0.1 is invoking the above APIs on the Main Thread as expected.

Can you please look into it?

Thanks.

alvarshahanji commented 1 week ago

@pm-vishal-chougule as you mentioned it works as expected in case of official PubMatic adapter, the issue is specific to the custom adapter.

We will not be able to fix it because of the limited support for custom network integration.

The original issue with destroy() should be fixed with SDK 13.0.1.