侧边栏壁纸
博主头像
火腾

行动起来,活在当下

  • 累计撰写 7 篇文章
  • 累计创建 9 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

完整指南:Cocos Creator Android 项目适配 Android 35 并集成 AdMob 激励广告

温馨提示:
本文最后更新于2025-08-01,若内容或图片失效,请留言反馈。 本文章权益归属火腾(www.firedance.cn),转载请注明来源于火腾(www.firedance.cn)。

Cocoscreator官方插件集成Admob只做了3.7.x的版本,并且Android 35还不能用...无力吐槽下准备自己做,先从比较多项目使用的2.4.x版本做集成。
将 Cocos Creator 项目适配到最新 Android SDK 35 并集成 AdMob 激励广告是一项复杂但必要的工作。本文详细记录了从环境配置到广告集成的完整流程,涵盖 Gradle 配置、AndroidX 支持、Java 原生接口开发以及 JavaScript 交互等关键步骤,旨在为开发者提供可操作的参考模板。特别针对 Cocos Creator 2.4.14 版本,结合 Android Studio JDK 设置和 JavaScript 调用调整,提供优化后的实现方案。环境准备基础环境

  • Cocos Creator:2.4.14

  • Android Studio:最新版本

  • Android SDK:35

  • Java:17(必需)

  • Gradle:8.5

项目结构Cocos Creator 2.4.14 默认生成的 Android 项目结构如下:

proj.android-studio/
├── app/
│   ├── build.gradle
│   ├── AndroidManifest.xml
│   └── src/org/cocos2dx/javascript/
│       └── CocosPlatformHelper.java
├── build.gradle
├── gradle.properties
└── gradle/wrapper/gradle-wrapper.properties

第一步:配置 Gradle JDKAndroid Gradle Plugin (AGP) 8.1.4 要求 Java 17,因此需要正确配置 Gradle JDK。以下是基于 Android Studio 的配置步骤:

  1. 打开 Android Studio 设置:

    • Windows:File → Settings

    • macOS:Android Studio → Preferences

  2. 导航到 Gradle 设置:

    • Build, Execution, Deployment → Build Tools → Gradle

  3. 配置 Gradle JDK:

    • 在 “Gradle JDK” 下拉菜单中选择 “Embedded JDK” 或指向 Java 17 的路径(如图所示,当前使用 jbr-21 JetBrains Runtime 21.0.6)。

    • 确保 “Distribution” 设置为 “Wrapper”。

    • 点击 “Apply” 和 “OK”。

参考截图: Android Studio JDK 设置注意:通过 Android Studio 配置 Gradle JDK 比直接修改配置文件更安全,避免路径或版本兼容性问题。第二步:升级 Gradle 和 Android Gradle Plugin2.1 更新根目录 build.gradle修改根目录下的 build.gradle,确保支持 Android SDK 35:

gradle

buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:8.1.4'
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        flatDir {
            dirs 'libs'
        }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

2.2 更新 Gradle Wrapper修改 gradle/wrapper/gradle-wrapper.properties,使用 Gradle 8.5:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true

第三步:配置 gradle.properties为适配 Android 35 和 AdMob,需启用 AndroidX 并设置相关 SDK 版本:

PROP_COMPILE_SDK_VERSION=35
PROP_MIN_SDK_VERSION=21
PROP_TARGET_SDK_VERSION=35
PROP_BUILD_TOOLS_VERSION=34.0.0
PROP_APP_ABI=armeabi-v7a:arm64-v8a

RELEASE_STORE_FILE=D:/Soft/cocos/editors/Creator/2.4.14/resources/static/build-templates/native/debug.keystore
RELEASE_STORE_PASSWORD=123456
RELEASE_KEY_ALIAS=debug_keystore
RELEASE_KEY_PASSWORD=123456

android.injected.testOnly=false
android.enableJetifier=true
android.useAndroidX=true

关键点:

  • 移除 org.gradle.java.home,通过 Android Studio 配置更可靠。

  • android.enableJetifier=true 和 android.useAndroidX=true 是 AdMob 集成的必要条件。

  • SDK 版本升级到 35,确保兼容性。

第四步:添加 AdMob 依赖在 app/build.gradle 中添加 AdMob SDK 依赖:

dependencies {
    implementation fileTree(dir: '../libs', include: ['*.jar','*.aar'])
    implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
    implementation fileTree(dir: "D:/Soft/cocos/editors/Creator/2.4.14/resources/cocos2d-x/cocos/platform/android/java/libs", include: ['*.jar'])
    implementation project(':libcocos2dx')
    implementation 'com.google.android.gms:play-services-ads:22.6.0'
}

第五步:配置 AndroidManifest.xml在 app/AndroidManifest.xml 中添加网络权限和 AdMob 配置:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:installLocation="auto">

    <uses-feature android:glEsVersion="0x00020000" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:usesCleartextTraffic="true"
        android:icon="@mipmap/ic_launcher">
        
        <meta-data android:name="android.app.lib_name" android:value="cocos2djs" />
        <meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy" />

        <activity
            android:name="org.cocos2dx.javascript.AppActivity"
            android:screenOrientation="portrait"
            android:configChanges="orientation|keyboardHidden|screenSize|screenLayout|uiMode"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:launchMode="singleTask"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

注意:

  • 将 ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy 替换为真实的 AdMob 应用 ID。

  • 网络权限对广告加载至关重要。

  • 保留 Cocos Creator 2.4.14 的默认配置。

第六步:开发 AdMob 原生接口创建 CocosPlatformHelper.java 实现 AdMob 激励广告的加载和显示逻辑:

package org.cocos2dx.javascript;

import android.app.Activity;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.rewarded.RewardedAd;
import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback;
import com.google.android.gms.ads.OnUserEarnedRewardListener;
import com.google.android.gms.ads.rewarded.RewardItem;
import androidx.annotation.NonNull;

public class CocosPlatformHelper {
    private static final String TAG = "CocosPlatformHelper";
    private static Activity activity;
    private static RewardedAd rewardedAd;
    private static boolean isLoading = false;
    private static boolean showSuccess = false;
    private static Handler handler = new Handler(Looper.getMainLooper());
    private static final String REWARDED_AD_UNIT_ID = "ca-app-pub-xxxxxxxxxxxxxxxx/zzzzzzzzzz";

    public static void init(Activity mainActivity) {
        Log.d(TAG, "Initializing CocosPlatformHelper");
        activity = mainActivity;
        if (activity == null) {
            Log.e(TAG, "Activity is null during initialization");
            return;
        }
        try {
            Log.d(TAG, "Starting AdMob SDK initialization...");
            MobileAds.initialize(activity, initializationStatus -> {
                Log.d(TAG, "AdMob SDK initialized successfully");
                loadRewardedAd();
            });
        } catch (Exception e) {
            Log.e(TAG, "Failed to initialize AdMob SDK: " + e.getMessage());
        }
    }

    private static void loadRewardedAd() {
        if (activity == null || isLoading) {
            Log.d(TAG, activity == null ? "Cannot load ad: activity is null" : "Ad is already loading");
            return;
        }
        try {
            Log.d(TAG, "Loading rewarded ad...");
            isLoading = true;
            AdRequest adRequest = new AdRequest.Builder().build();
            RewardedAd.load(activity, REWARDED_AD_UNIT_ID, adRequest, new RewardedAdLoadCallback() {
                @Override
                public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
                    Log.e(TAG, "Rewarded ad failed to load: " + loadAdError.getMessage());
                    rewardedAd = null;
                    isLoading = false;
                }

                @Override
                public void onAdLoaded(@NonNull RewardedAd ad) {
                    Log.d(TAG, "Rewarded ad loaded successfully");
                    rewardedAd = ad;
                    isLoading = false;
                    ad.setFullScreenContentCallback(new FullScreenContentCallback() {
                        @Override
                        public void onAdDismissedFullScreenContent() {
                            Log.d(TAG, "Ad was dismissed");
                            if (showSuccess) {
                                postMessageToJs("2");
                                showSuccess = false;
                            }
                            rewardedAd = null;
                            loadRewardedAd();
                        }

                        @Override
                        public void onAdFailedToShowFullScreenContent(@NonNull AdError adError) {
                            Log.e(TAG, "Ad failed to show: " + adError.getMessage());
                            postMessageToJs("2");
                        }

                        @Override
                        public void onAdShowedFullScreenContent() {
                            Log.d(TAG, "Ad showed fullscreen content");
                            showSuccess = true;
                        }
                    });
                }
            });
        } catch (Exception e) {
            Log.e(TAG, "Exception while loading rewarded ad: " + e.getMessage());
            isLoading = false;
        }
    }

    public static void ShowRewardAD() {
        Log.d(TAG, "ShowRewardAD called from JS");
        if (activity == null) {
            Log.e(TAG, "Activity is null, cannot show ad");
            return;
        }
        activity.runOnUiThread(() -> {
            if (rewardedAd != null) {
                Log.d(TAG, "Showing rewarded ad");
                showSuccess = false;
                rewardedAd.show(activity, rewardItem -> {
                    Log.d(TAG, "User earned reward: " + rewardItem.getAmount() + " " + rewardItem.getType());
                    showSuccess = false;
                    postMessageToJs("1");
                });
            } else {
                Log.d(TAG, "The rewarded ad wasn't ready yet");
                postMessageToJs("2");
                if (!isLoading) {
                    loadRewardedAd();
                }
            }
        });
    }

    public static void LoadRewardAD() {
        Log.d(TAG, "LoadRewardAD called from JS");
        if (!isLoading) {
            loadRewardedAd();
        }
    }

    public static boolean IsRewardAdReady() {
        boolean isReady = rewardedAd != null;
        Log.d(TAG, "IsRewardAdReady: " + isReady);
        return isReady;
    }

    // 使用 Cocos2dxHelper 适配 Cocos Creator 2.4.14
    private static void postMessageToJs(final String msg) {
        Cocos2dxHelper.runOnGLThread(new Runnable() {
            @Override
            public void run() {
                Log.v(TAG, "[Android] postMessageToJs:" + msg);
                String script = String.format("AndroidReceiveNative(%s);", msg);
                Cocos2dxJavascriptJavaBridge.evalString(script);
            }
        });
    }
}

关键点:

  • 将 REWARDED_AD_UNIT_ID 替换为真实的 AdMob 激励广告单元 ID。

  • 使用 showSuccess 标志确保广告状态准确。

  • postMessageToJs 方法已调整为使用 Cocos2dxHelper.runOnGLThread,适配 Cocos Creator 2.4.14 的线程模型。

第七步:初始化 AdMob在 AppActivity.java 中初始化 AdMob:

package org.cocos2dx.javascript;

import org.cocos2dx.lib.Cocos2dxActivity;

public class AppActivity extends Cocos2dxActivity {
    @Override
    protected void onCreate(android.os.Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        CocosPlatformHelper.init(this);
    }
}

第八步:JavaScript 端集成在 JavaScript 代码中添加回调和调用逻辑:

window.AndroidReceiveNative = function(msg) {
    console.log("Received from Android:", msg);
    if (msg === "1") {
        console.log("User earned reward");
        // 处理奖励逻辑,例如增加金币或道具
    } else if (msg === "2") {
        console.log("Ad failed or closed");
        // 处理广告失败或关闭逻辑
    }
};

window.showRewardAd = function() {
    if (cc.sys.os === cc.sys.OS_ANDROID) {
        jsb.reflection.callStaticMethod("org/cocos2dx/javascript/CocosPlatformHelper", "ShowRewardAD", "()V");
    }
};

window.isRewardAdReady = function() {
    if (cc.sys.os === cc.sys.OS_ANDROID) {
        return jsb.reflection.callStaticMethod("org/cocos2dx/javascript/CocosPlatformHelper", "IsRewardAdReady", "()Z");
    }
    return false;
};

window.loadRewardAd = function() {
    if (cc.sys.os === cc.sys.OS_ANDROID) {
        jsb.reflection.callStaticMethod("org/cocos2dx/javascript/CocosPlatformHelper", "LoadRewardAD", "()V");
    }
};

第九步:构建与测试

9.1 构建项目

9.2 测试流程

  1. 安装生成的 APK 到测试设备。

  2. 使用 adb logcat 查看 AdMob 相关日志。

  3. 在游戏中调用 showRewardAd() 测试广告显示。

  4. 验证 JavaScript 回调是否正常触发。

常见问题与解决方案

  1. Gradle JDK 配置错误

    • 错误:Invalid Gradle JDK configuration found

    • 解决:在 Android Studio 中选择 “Embedded JDK” 或 Java 17 路径。

  2. Android 资源链接失败

    • 错误:Android resource linking failed

    • 解决:确保 SDK 版本和构建工具版本正确。

  3. JavaScript 调用崩溃

    • 错误:crash_dump64

    • 解决:

      • 确保 JavaScript 回调函数正确定义。

      • 使用 Cocos2dxHelper.runOnGLThread 确保主线程调用。

      • 添加异常处理。

  4. 广告加载失败

    • 解决:

      • 检查网络连接。

      • 验证 AdMob 广告单元 ID。

      • 将设备添加到 AdMob 测试设备列表。

注意事项

  1. 版本兼容性:Android SDK 35 要求 AGP 8.1.4+ 和 Java 17。

  2. AndroidX 支持:AdMob 依赖 AndroidX,必须启用 Jetifier。

  3. 网络权限:确保 AndroidManifest.xml 中包含网络权限。

  4. 测试广告:开发阶段使用 AdMob 测试广告单元 ID。

  5. 线程安全:Cocos Creator 2.4.14 需使用 Cocos2dxHelper.runOnGLThread 处理 UI 操作。

  6. Gradle JDK 配置:优先使用 Android Studio 界面配置。

总结通过以上步骤,我们成功将 Cocos Creator 2.4.14 Android 项目适配到 Android SDK 35 并集成了 AdMob 激励广告。关键在于合理的版本管理、适配 Cocos Creator 线程模型的原生接口设计以及可靠的 JavaScript 交互机制。本指南可作为其他 Cocos Creator 2.4.14 项目集成广告功能的模板,帮助开发者高效实现类似需求。

0

评论区