Skip to main content
Version: v2.0

PremiumAds Google AdMob Adapter V2 — Cocos2d-x

Integrate PremiumAds as a mediation ad source in your Cocos2d-x C++ game. The adapter is a Google AdMob mediation custom event — your game continues to call Google Mobile Ads SDK to load ads; AdMob's waterfall picks PremiumAds when configured.

Supported formats: Banner (incl. MREC 300×250, Leaderboard, Adaptive), Interstitial, Rewarded, Rewarded Interstitial, Native, App Open

Reference repo: premium-ads/googleads-adapter-v2-cocos2dx

Prerequisites​

RequirementVersion
Cocos2d-x3.15.x (tested 3.15.1)
Android StudioHedgehog or newer
Android Gradle Plugin8.2.2+
Gradle8.2+
Android NDKr25c or newer (tested r27)
Android minSdk21
Xcode15+ (tested 17)
iOS deployment target13.0+
Google Mobile Ads SDK (Android)play-services-ads:22.2.0+ (23.6.0+ recommended; 22.x needs adapter 1.0.11+)
Google Mobile Ads SDK (iOS)Google-Mobile-Ads-SDK ~> 13.0

Cocos2d-x 3.15.1 is from 2017 and requires toolchain modernization patches to build under modern Xcode/Android Studio (AGP 8 + Gradle 8 + NDK 27 on Android; deployment target 13.0 + a prebuilt-arch helper on iOS). The reference repo ships these patches inline so you can clone and build directly.

1. Copy the Plugin Files into Your Project​

From the reference repo, copy two folders into your Cocos2d-x project's Classes/:

  • Classes/PremiumAdsAdapter/ — the plugin (1 method: setDebug())
  • Classes/AdMobBridge/ — the hand-rolled GMA C++ bridge for all 6 ad formats
YourGame/
├── Classes/
│ ├── PremiumAdsAdapter/PremiumAdsAdapter.{h,cpp}
│ └── AdMobBridge/
│ ├── AdMobBridgeCpp.h
│ ├── Banner.{h,cpp}
│ ├── Interstitial.{h,cpp}
│ ├── Rewarded.{h,cpp}
│ ├── RewardedInterstitial.{h,cpp}
│ ├── AppOpen.{h,cpp}
│ └── NativeAd.{h,cpp}

Also copy the matching native peers:

  • Android Java: proj.android-studio/app/src/main/java/net/premiumads/cocos2dx/ (one bridge class per format)
  • iOS Obj-C++: proj.ios_mac/ios/{PremiumAdsAdapter,AdMobBridge}/ (.h + .mm)
  • Android layout: proj.android-studio/app/src/main/res/layout/native_ad_template.xml (Native ad template)

2. Android — Gradle Dependencies​

proj.android-studio/build.gradle

allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://repo.premiumads.net/artifactory/mobile-ads-sdk/' }
}
}

proj.android-studio/app/build.gradle

android {
namespace 'com.your.package'
compileSdkVersion 34
ndkVersion "27.0.12077973"

defaultConfig {
applicationId 'com.your.package'
minSdkVersion 21
targetSdkVersion 34
multiDexEnabled true
externalNativeBuild {
ndkBuild { abiFilters 'armeabi-v7a', 'arm64-v8a' }
}
}
}

dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.gms:play-services-ads:23.6.0'
implementation 'net.premiumads.sdk:admob-adapter-v2:1.0.12'
}

3. Android — Manifest & Application init​

AndroidManifest.xml (note: AdMob meta-data must be at <application> level, not <activity>):

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>

<application android:name=".MainApplication" ...>
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY" />
<meta-data
android:name="android.app.lib_name"
android:value="cocos2dcpp"/>
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="@android:style/Theme.Translucent" />
</application>
</manifest>

MainApplication.java — initialize MobileAds before the Cocos2d-x activity starts:

package com.your.package;

import androidx.multidex.MultiDexApplication;
import com.google.android.gms.ads.MobileAds;

public final class MainApplication extends MultiDexApplication {
@Override public void onCreate() {
super.onCreate();
MobileAds.initialize(this, status -> { /* ready */ });
}
}

4. Android — Android.mk​

Add the bridge sources to LOCAL_SRC_FILES and use LOCAL_WHOLE_STATIC_LIBRARIES so engine JNI symbols are exported in the final libcocos2dcpp.so:

LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/PremiumAdsAdapter/PremiumAdsAdapter.cpp
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge/Banner.cpp
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge/Interstitial.cpp
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge/Rewarded.cpp
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge/RewardedInterstitial.cpp
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge/AppOpen.cpp
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge/NativeAd.cpp

LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge \
$(LOCAL_PATH)/../../../../../Classes/PremiumAdsAdapter

LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static

5. iOS — Podfile​

platform :ios, '13.0'
use_frameworks!

target 'YourGame-mobile' do
pod 'Google-Mobile-Ads-SDK', '~> 13.0'
pod 'PremiumAdsGoogleAdapter', '~> 1.0.10'
end

Run pod install.

6. iOS — Info.plist & AppDelegate​

Add to Info.plist:

<key>GADApplicationIdentifier</key>
<string>ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY</string>
<key>NSUserTrackingUsageDescription</key>
<string>This identifier will be used to deliver personalized ads to you.</string>
<key>SKAdNetworkItems</key>
<array>
<!-- See https://developers.google.com/admob/ios/ios14 for the canonical list. -->
</array>

In AppDelegate.m / AppController.mm — initialize MobileAds before Cocos2d-x bootstraps:

#import <GoogleMobileAds/GoogleMobileAds.h>

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GADMobileAds.sharedInstance startWithCompletionHandler:nil];
// ... existing Cocos2d-x bootstrap
return YES;
}

7. Use the C++ API in Your Game​

#include "PremiumAdsAdapter/PremiumAdsAdapter.h"
#include "AdMobBridge/Banner.h"
#include "AdMobBridge/Interstitial.h"
#include "AdMobBridge/Rewarded.h"

// Once at app start (verbose adapter logs):
premiumads::PremiumAdsAdapter::setDebug(true);

// Banner
admob::Banner::setListener([](admob::BannerEvent e, const std::string& m) {
cocos2d::log("[Banner] event=%d %s", (int)e, m.c_str());
});
admob::Banner::create("ca-app-pub-XXX/YYY",
admob::BannerSize::MediumRectangle_300x250, // or Banner_320x50, Leaderboard_728x90, Adaptive
admob::BannerPosition::Bottom);

// Interstitial (load → show pattern)
admob::Interstitial::setListener(...);
admob::Interstitial::load("ca-app-pub-XXX/YYY");
// later, when you want to display:
if (admob::Interstitial::isReady()) admob::Interstitial::show();

// Rewarded — same pattern, listener also receives UserEarnedReward(7) with msg "type|amount"
admob::Rewarded::load("ca-app-pub-XXX/YYY");
admob::Rewarded::show();

// NativeAd — bind() overlays a native UIView/FrameLayout at game-coords
admob::NativeAd::load("ca-app-pub-XXX/YYY");
// after Loaded event:
admob::NativeAd::bind(designX, designY, designW, designH);

8. Configure AdMob Custom Event​

For each ad unit you want to mediate through PremiumAds, add a custom event in the AdMob console:

FieldValue
Class name (Android)net.premiumads.sdk.adapter.PremiumAdsAdapter
Class name (iOS)PremiumAdsAdapter
ParameterPremiumAds Adunit
eCPMstart at $0.10 to test, then tune

After publishing the mediation change (5–30 min propagation), filter logs for [PremiumAdsAdapter]. If you see the line, the waterfall reached PremiumAds.

Troubleshooting​

  • UnsatisfiedLinkError: nativeSetAudioDeviceInfo at boot: the manifest's android.app.lib_name meta-data must be a child of <application>, NOT <activity>. Cocos2dxActivity.onLoadNativeLibraries() reads it via PackageManager.GET_META_DATA on ApplicationInfo.
  • JNI symbols missing despite .so build success: use LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static (not LOCAL_STATIC_LIBRARIES) so engine symbols stay in the final dynamic export table.
  • iOS link fails with "building for 'iOS-simulator', but linking in object file built for 'iOS'": Cocos2d-x 3.15.1 ships prebuilt third-party libs as arm64-iphoneos only. Run the reference repo's tools/strip-prebuilt-platform.sh once after symlinking the engine — it strips LC_VERSION_MIN_IPHONEOS from prebuilt arm64 objects so ld treats them as platform-neutral, and patches the two iOS 26 SDK source compatibility issues (CCFontAtlas.cpp iconv_t cast + CCFileUtils.cpp system() guard).
  • HelloWorld::init() SIGSEGV on modern NDK: the stock cocos2d-x 3.15.1 template scene crashes on NDK 27. Replace with your own scene or copy the reference repo's HelloWorldScene.cpp.
  • Adapter never appears in MobileAds.initialize adapter map: confirm the AAR/Pod is actually linked (./gradlew :app:dependencies | grep premium, pod list | grep PremiumAds).

What gets shipped​

PremiumAds Cocos2d-x integration is mediation custom-event only — your game continues to use Google Mobile Ads SDK directly. The adapter activates only when AdMob's waterfall picks it for a given ad unit. No code changes to your existing ad loading logic are required beyond installing the plugin.

Demo project​

Clone the reference repo for a working sample with all 6 formats wired up:

git clone https://github.com/premium-ads/googleads-adapter-v2-cocos2dx.git
cd googleads-adapter-v2-cocos2dx
ln -s ~/cocos-installs/cocos2d-x-cocos2d-x-3.15.1 cocos2d

# Android
cd proj.android-studio && ./gradlew assembleDebug

# iOS — Apple Silicon Mac simulator: run the platform-strip script first
cd .. && bash tools/strip-prebuilt-platform.sh
cd proj.ios_mac/ios && pod install
xcodebuild -workspace GoogleAdsCocos2dxSample.xcworkspace \
-scheme GoogleAdsCocos2dxSample-mobile \
-sdk iphonesimulator build CODE_SIGNING_ALLOWED=NO