Consider your contexts when mediating

For Android developers, Context objects can be tricky. To start with, android.content.Context has a zillion subclasses, some of which are really specific (I’m looking at you, NotificationCompatSideChannelService). On top of that, there are a bunch of available calls to retrieve the current Context, all of which seem slightly different. Once you start talking about passing these objects from one part of an app to another, which happens during AdMob mediation, it can get confusing in a hurry. In order to keep things straight, engineers building Android custom events and mediation adapters need to make sure they’re handling Contexts properly.

If you’ve ever built a custom event or mediation adapter for AdMob, you’re probably familiar with these two methods:


requestInterstitialAd(Context context,
CustomEventInterstitialListener listener,
String serverParameter,
MediationAdRequest mediationAdRequest,
Bundle customEventExtras)

requestInterstitialAd(Context context,
MediationInterstitialListener listener,
Bundle serverParameters,
MediationAdRequest mediationAdRequest,
Bundle mediationExtras)

They’re from the CustomEventInterstitial and MediationInterstitialAdapter interfaces, respectively, and are used to request interstitial ads from custom events and adapters. Both include a Context parameter that can be used to retrieve information about the execution environment, query permissions, and access user preferences. In most cases, that object ends up being the Activity an app is displaying when its ad request is made (Activity is a subclass of Context), but that’s not guaranteed.

For example, consider an app that switches quickly from one Activity to another, and occasionally shows an interstitial ad during one of the transitions. Requesting a new ad in each onCreate method will likely waste resources, so offloading that work to a separate class that lives outside the Activity lifecycle is a common solution. Because that class isn’t an Activity, though, it can’t use itself as a Context, and instead must request interstitials using the Application object (another Context subclass). If the app uses custom event and adapter classes that were only tested with Activity objects, they might break!

The best practice here is to make sure to test your custom events and adapters with both Activity and Application objects prior to releasing them. A reliable custom event needs to operate the same no matter which is provided, and the same goes for adapters. If, for some reason, the SDK you’re adapting just can’t work with an Application object as the context parameter, you can always trap this using instanceof and log the error:


@Override
Public void requestInterstitialAd(Context context,
CustomEventInterstitialListener listener,
String serverParameter,
MediationAdRequest mediationAdRequest,
Bundle customEventExtras) {
if (!(context instanceof Activity)) {
Log.w(“Example”, “Context not an Activity. Returning error!”);
listener.onAdFailedToLoad(AdRequest.ERROR_CODE_INVALID_REQUEST);
}

// ... code to request an ad using the Activity context ...
}

If you have technical questions about activities, contexts, or anything else relating to the Google Mobile Ads SDK, stop by our forum.