uni-app 广告集成

章节介绍

广告是移动应用的重要变现方式之一,它能够帮助开发者通过应用获得收益。uni-app 作为跨平台开发框架,支持集成多种广告平台,实现全平台的广告展示和收益管理。本章节将详细介绍 uni-app 广告集成的方法和最佳实践。

核心知识点

1. 广告类型概述

在移动应用中,常见的广告类型包括:

  • 横幅广告(Banner):位于应用顶部或底部的横幅式广告
  • 插屏广告(Interstitial):在应用切换场景时全屏展示的广告
  • 激励视频广告(Rewarded Video):用户观看视频后获得奖励的广告
  • 原生广告(Native):与应用内容融合的广告形式
  • 开屏广告(Splash):应用启动时展示的广告
  • 信息流广告(Feed):嵌入在内容流中的广告
  • 横幅视频广告(Banner Video):以视频形式展示的横幅广告

2. 常用广告平台

在 uni-app 中,常用的广告平台包括:

  • 穿山甲广告:字节跳动旗下的广告平台,支持多平台
  • 优量汇(广点通):腾讯旗下的广告平台,适合有腾讯生态需求的应用
  • 百度联盟:百度旗下的广告平台,整合百度生态
  • 快手联盟:快手旗下的广告平台,适合短视频类应用
  • AdMob:Google 旗下的全球广告平台,适合海外应用
  • AppLovin:全球领先的移动广告平台
  • IronSource:全球领先的移动广告平台

3. 广告系统架构

一个完整的广告系统通常包含以下组件:

  • 广告 SDK:集成在应用中的广告软件开发工具包
  • 广告请求:应用向广告平台请求广告的过程
  • 广告加载:广告资源的下载和预处理
  • 广告展示:广告在应用中的呈现
  • 广告交互:用户与广告的交互行为
  • 广告回调:广告事件的回调处理
  • 收益统计:广告收益的数据统计和管理

4. uni-app 广告集成方法

uni-app 提供了多种广告集成方式:

4.1 使用 uni-app 插件市场的广告插件

uni-app 插件市场提供了多种广告插件,如穿山甲广告、优量汇等。

优势

  • 集成简单,一键导入
  • 跨平台兼容
  • 与 uni-app 深度集成

4.2 集成第三方广告 SDK

对于有特殊需求的应用,可以选择集成第三方广告 SDK。

步骤

  1. 在对应广告平台的开发者后台注册应用
  2. 获取广告所需的 AppID、AppKey 等配置
  3. 在 uni-app 中通过原生插件或条件编译集成 SDK
  4. 实现广告的加载、展示和回调处理

4.3 聚合广告平台

对于需要最大化收益的应用,可以选择集成聚合广告平台,如 TopOn、AdMost 等。

优势

  • 整合多个广告平台,提高填充率
  • 智能广告选择,最大化收益
  • 统一的广告管理和数据分析

5. 广告收益优化

5.1 广告位设计

  • 位置选择:选择用户视线焦点和停留时间长的位置
  • 尺寸设计:根据广告类型和平台要求设计合适的广告尺寸
  • 展示频率:合理控制广告展示频率,避免过度打扰用户
  • 样式融合:广告样式与应用风格保持一致,提高用户接受度

5.2 流量优化

  • 用户分群:根据用户特征和行为对广告进行定向投放
  • 时段优化:根据不同时段的广告价格调整广告展示策略
  • 地域优化:根据不同地区的广告价格和填充率调整投放策略
  • 设备优化:根据设备类型和网络环境调整广告类型

5.3 收益分析

  • eCPM 分析:分析不同广告平台、广告类型和广告位的 eCPM
  • 填充率分析:分析不同广告平台的填充率
  • 点击率分析:分析不同广告类型和位置的点击率
  • 收益趋势:分析收益的日、周、月趋势

6. 广告合规性

6.1 平台政策

  • 应用商店政策:遵守各应用商店的广告政策
  • 广告平台政策:遵守各广告平台的投放政策
  • 隐私政策:遵守各地区的隐私保护法规

6.2 用户体验

  • 广告标识:明确标识广告内容,避免误导用户
  • 关闭按钮:提供清晰的广告关闭方式
  • 广告频率:合理控制广告展示频率,避免过度打扰用户
  • 广告质量:确保广告内容健康、合法

实用案例

案例:实现应用广告功能

需求分析

开发一个内容应用的广告系统,实现以下功能:

  1. 集成穿山甲广告平台
  2. 实现横幅广告、插屏广告和激励视频广告
  3. 优化广告展示策略,提高收益
  4. 实现广告收益统计和分析

技术方案

使用 uni-app 插件市场的穿山甲广告插件实现广告功能,结合后端系统实现广告收益统计和分析。

代码实现

1. 集成穿山甲广告插件

在 uni-app 插件市场搜索并导入穿山甲广告插件,然后在 manifest.json 中配置:

// manifest.json
{
  "name": "",
  "appid": "",
  "description": "",
  "versionName": "",
  "versionCode": "",
  "transformPx": true,
  "app-plus": {
    "distribute": {
      "android": {
        "package": "",
        "permissions": [
          "ACCESS_NETWORK_STATE",
          "ACCESS_WIFI_STATE",
          "INTERNET",
          "READ_PHONE_STATE",
          "WRITE_EXTERNAL_STORAGE",
          "READ_EXTERNAL_STORAGE"
        ]
      },
      "ios": {
        "bundleId": "",
        "infoPlist": {
          "NSAppTransportSecurity": {
            "NSAllowsArbitraryLoads": true
          },
          "NSUserTrackingUsageDescription": "此标识符将用于向您推荐个性化广告"
        }
      }
    }
  },
  "mp-weixin": {
    "appid": "",
    "setting": {
      "urlCheck": false
    }
  },
  "ad": {
    "csj": {
      "appId": "your_csj_appid",
      "appKey": "your_csj_appkey"
    }
  }
}
2. 广告服务封装

创建一个广告服务模块,封装广告相关功能:

// utils/adService.js
class AdService {
  constructor() {
    this.isInitialized = false;
    this.bannerAd = null;
    this.interstitialAd = null;
    this.rewardedVideoAd = null;
    this.nativeAd = null;
  }
  
  // 初始化广告服务
  init() {
    if (this.isInitialized) return;
    
    // 初始化穿山甲广告
    this.initCSJAd();
    
    this.isInitialized = true;
  }
  
  // 初始化穿山甲广告
  initCSJAd() {
    // 实际应用中应调用穿山甲广告 SDK 的初始化方法
    console.log('穿山甲广告初始化');
  }
  
  // 创建横幅广告
  createBannerAd(options = {}) {
    if (!this.isInitialized) {
      console.warn('广告服务未初始化');
      return null;
    }
    
    const adUnitId = options.adUnitId || 'your_banner_ad_unit_id';
    const style = {
      left: options.left || 0,
      top: options.top || 0,
      width: options.width || 375,
      height: options.height || 50
    };
    
    // 创建横幅广告实例
    this.bannerAd = uni.createBannerAd({
      adUnitId: adUnitId,
      style: style
    });
    
    // 监听广告加载事件
    this.bannerAd.onLoad(() => {
      console.log('横幅广告加载成功');
      options.onLoad && options.onLoad();
    });
    
    // 监听广告错误事件
    this.bannerAd.onError((err) => {
      console.log('横幅广告加载失败:', err);
      options.onError && options.onError(err);
    });
    
    // 监听广告点击事件
    this.bannerAd.onClose(() => {
      console.log('横幅广告关闭');
      options.onClose && options.onClose();
    });
    
    // 加载广告
    this.bannerAd.load();
    
    return this.bannerAd;
  }
  
  // 显示横幅广告
  showBannerAd() {
    if (this.bannerAd) {
      this.bannerAd.show();
    }
  }
  
  // 隐藏横幅广告
  hideBannerAd() {
    if (this.bannerAd) {
      this.bannerAd.hide();
    }
  }
  
  // 销毁横幅广告
  destroyBannerAd() {
    if (this.bannerAd) {
      this.bannerAd.destroy();
      this.bannerAd = null;
    }
  }
  
  // 创建插屏广告
  createInterstitialAd(options = {}) {
    if (!this.isInitialized) {
      console.warn('广告服务未初始化');
      return null;
    }
    
    const adUnitId = options.adUnitId || 'your_interstitial_ad_unit_id';
    
    // 创建插屏广告实例
    this.interstitialAd = uni.createInterstitialAd({
      adUnitId: adUnitId
    });
    
    // 监听广告加载事件
    this.interstitialAd.onLoad(() => {
      console.log('插屏广告加载成功');
      options.onLoad && options.onLoad();
    });
    
    // 监听广告错误事件
    this.interstitialAd.onError((err) => {
      console.log('插屏广告加载失败:', err);
      options.onError && options.onError(err);
    });
    
    // 监听广告关闭事件
    this.interstitialAd.onClose((res) => {
      console.log('插屏广告关闭:', res);
      options.onClose && options.onClose(res);
    });
    
    // 加载广告
    this.interstitialAd.load();
    
    return this.interstitialAd;
  }
  
  // 显示插屏广告
  showInterstitialAd() {
    if (this.interstitialAd) {
      this.interstitialAd.show().catch((err) => {
        console.log('插屏广告显示失败:', err);
      });
    }
  }
  
  // 销毁插屏广告
  destroyInterstitialAd() {
    if (this.interstitialAd) {
      this.interstitialAd.destroy();
      this.interstitialAd = null;
    }
  }
  
  // 创建激励视频广告
  createRewardedVideoAd(options = {}) {
    if (!this.isInitialized) {
      console.warn('广告服务未初始化');
      return null;
    }
    
    const adUnitId = options.adUnitId || 'your_rewarded_video_ad_unit_id';
    
    // 创建激励视频广告实例
    this.rewardedVideoAd = uni.createRewardedVideoAd({
      adUnitId: adUnitId
    });
    
    // 监听广告加载事件
    this.rewardedVideoAd.onLoad(() => {
      console.log('激励视频广告加载成功');
      options.onLoad && options.onLoad();
    });
    
    // 监听广告错误事件
    this.rewardedVideoAd.onError((err) => {
      console.log('激励视频广告加载失败:', err);
      options.onError && options.onError(err);
    });
    
    // 监听广告关闭事件
    this.rewardedVideoAd.onClose((res) => {
      console.log('激励视频广告关闭:', res);
      if (res && res.isEnded) {
        // 用户观看完视频,发放奖励
        options.onReward && options.onReward();
      } else {
        // 用户未观看完视频
        options.onClose && options.onClose(res);
      }
    });
    
    // 加载广告
    this.rewardedVideoAd.load();
    
    return this.rewardedVideoAd;
  }
  
  // 显示激励视频广告
  showRewardedVideoAd() {
    if (this.rewardedVideoAd) {
      this.rewardedVideoAd.show().catch((err) => {
        console.log('激励视频广告显示失败:', err);
      });
    }
  }
  
  // 销毁激励视频广告
  destroyRewardedVideoAd() {
    if (this.rewardedVideoAd) {
      this.rewardedVideoAd.destroy();
      this.rewardedVideoAd = null;
    }
  }
  
  // 创建原生广告
  createNativeAd(options = {}) {
    if (!this.isInitialized) {
      console.warn('广告服务未初始化');
      return null;
    }
    
    const adUnitId = options.adUnitId || 'your_native_ad_unit_id';
    
    // 创建原生广告实例
    this.nativeAd = uni.createNativeAd({
      adUnitId: adUnitId
    });
    
    // 监听广告加载事件
    this.nativeAd.onLoad((res) => {
      console.log('原生广告加载成功:', res);
      options.onLoad && options.onLoad(res);
    });
    
    // 监听广告错误事件
    this.nativeAd.onError((err) => {
      console.log('原生广告加载失败:', err);
      options.onError && options.onError(err);
    });
    
    // 加载广告
    this.nativeAd.load();
    
    return this.nativeAd;
  }
  
  // 销毁原生广告
  destroyNativeAd() {
    if (this.nativeAd) {
      this.nativeAd.destroy();
      this.nativeAd = null;
    }
  }
  
  // 上报广告曝光
  reportAdShow(adId) {
    if (this.nativeAd) {
      this.nativeAd.reportAdShow({ adId: adId });
    }
  }
  
  // 上报广告点击
  reportAdClick(adId) {
    if (this.nativeAd) {
      this.nativeAd.reportAdClick({ adId: adId });
    }
  }
}

export default new AdService();
3. 在页面中使用广告服务
<!-- pages/home/home.vue -->
<template>
  <view class="home-container">
    <view class="content">
      <!-- 应用内容 -->
      <text class="title">欢迎使用 uni-app 广告集成示例</text>
      <text class="description">本示例展示了如何在 uni-app 中集成各种类型的广告</text>
      
      <view class="button-group">
        <button class="button" @click="showInterstitialAd">显示插屏广告</button>
        <button class="button" @click="showRewardedVideoAd">观看激励视频</button>
      </view>
      
      <view class="reward-info" v-if="showRewardInfo">
        <text class="reward-text">🎉 恭喜获得 10 积分奖励!</text>
      </view>
    </view>
    
    <!-- 横幅广告容器 -->
    <view class="banner-container" v-if="showBanner"></view>
  </view>
</template>

<script>
import adService from '@/utils/adService.js';

export default {
  data() {
    return {
      showBanner: true,
      showRewardInfo: false
    };
  },
  onLoad() {
    // 初始化广告服务
    adService.init();
    
    // 创建横幅广告
    this.createBannerAd();
    
    // 创建插屏广告
    this.createInterstitialAd();
    
    // 创建激励视频广告
    this.createRewardedVideoAd();
  },
  onUnload() {
    // 销毁广告实例
    adService.destroyBannerAd();
    adService.destroyInterstitialAd();
    adService.destroyRewardedVideoAd();
  },
  methods: {
    // 创建横幅广告
    createBannerAd() {
      adService.createBannerAd({
        adUnitId: 'your_banner_ad_unit_id',
        style: {
          left: 0,
          top: 0,
          width: 375,
          height: 50
        },
        onLoad: () => {
          console.log('横幅广告加载成功');
          adService.showBannerAd();
        },
        onError: (err) => {
          console.log('横幅广告加载失败:', err);
          this.showBanner = false;
        }
      });
    },
    
    // 创建插屏广告
    createInterstitialAd() {
      adService.createInterstitialAd({
        adUnitId: 'your_interstitial_ad_unit_id',
        onLoad: () => {
          console.log('插屏广告加载成功');
        },
        onError: (err) => {
          console.log('插屏广告加载失败:', err);
        }
      });
    },
    
    // 显示插屏广告
    showInterstitialAd() {
      adService.showInterstitialAd();
    },
    
    // 创建激励视频广告
    createRewardedVideoAd() {
      adService.createRewardedVideoAd({
        adUnitId: 'your_rewarded_video_ad_unit_id',
        onLoad: () => {
          console.log('激励视频广告加载成功');
        },
        onError: (err) => {
          console.log('激励视频广告加载失败:', err);
        },
        onReward: () => {
          // 发放奖励
          this.giveReward();
        }
      });
    },
    
    // 显示激励视频广告
    showRewardedVideoAd() {
      adService.showRewardedVideoAd();
    },
    
    // 发放奖励
    giveReward() {
      // 实际应用中应调用后端 API 发放奖励
      this.showRewardInfo = true;
      setTimeout(() => {
        this.showRewardInfo = false;
      }, 3000);
    }
  }
};
</script>

<style scoped>
.home-container {
  position: relative;
  width: 100%;
  min-height: 100vh;
  background-color: #f5f5f5;
}

.content {
  padding: 40rpx 20rpx;
  text-align: center;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 20rpx;
}

.description {
  font-size: 28rpx;
  color: #666;
  margin-bottom: 40rpx;
  line-height: 44rpx;
}

.button-group {
  display: flex;
  flex-direction: column;
  gap: 20rpx;
  margin-bottom: 40rpx;
}

.button {
  padding: 20rpx;
  background-color: #1890ff;
  color: #fff;
  border-radius: 12rpx;
  font-size: 28rpx;
}

.reward-info {
  background-color: #f6ffed;
  border: 1rpx solid #b7eb8f;
  border-radius: 8rpx;
  padding: 20rpx;
  margin-top: 20rpx;
}

.reward-text {
  font-size: 28rpx;
  color: #52c41a;
}

.banner-container {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: 50px;
  background-color: #fff;
}
</style>
4. 广告收益统计服务

以下是一个简单的 Node.js 后端广告收益统计服务示例:

// server.js
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const moment = require('moment');

const app = express();
app.use(bodyParser.json());

// 连接数据库
mongoose.connect('mongodb://localhost:27017/ad-statistics', { useNewUrlParser: true, useUnifiedTopology: true });

// 广告收益记录模型
const AdRevenueRecord = mongoose.model('AdRevenueRecord', {
  adPlatform: String,
  adType: String,
  adUnitId: String,
  revenue: Number,
  impressions: Number,
  clicks: Number,
  ctr: Number,
  ecpm: Number,
  date: String,
  hour: Number,
  timestamp: Number
});

// 广告事件记录模型
const AdEventRecord = mongoose.model('AdEventRecord', {
  eventType: String, // impression, click, reward
  adPlatform: String,
  adType: String,
  adUnitId: String,
  userId: String,
  deviceId: String,
  timestamp: Number,
  date: String
});

// 广告事件上报 API
app.post('/ad/event', (req, res) => {
  const { eventType, adPlatform, adType, adUnitId, userId, deviceId } = req.body;
  
  // 创建事件记录
  const eventRecord = new AdEventRecord({
    eventType: eventType,
    adPlatform: adPlatform,
    adType: adType,
    adUnitId: adUnitId,
    userId: userId || 'anonymous',
    deviceId: deviceId || 'unknown',
    timestamp: Date.now(),
    date: moment().format('YYYY-MM-DD')
  });
  
  // 保存到数据库
  eventRecord.save((err) => {
    if (err) {
      console.error('保存广告事件记录失败:', err);
      res.json({ code: 1, message: '上报失败' });
    } else {
      console.log('广告事件记录保存成功:', eventType);
      res.json({ code: 0, message: '上报成功' });
    }
  });
});

// 广告收益上报 API
app.post('/ad/revenue', (req, res) => {
  const { adPlatform, adType, adUnitId, revenue, impressions, clicks } = req.body;
  
  // 计算 CTR 和 eCPM
  const ctr = impressions > 0 ? (clicks / impressions) * 100 : 0;
  const ecpm = impressions > 0 ? (revenue / impressions) * 1000 : 0;
  
  // 创建收益记录
  const revenueRecord = new AdRevenueRecord({
    adPlatform: adPlatform,
    adType: adType,
    adUnitId: adUnitId,
    revenue: revenue,
    impressions: impressions,
    clicks: clicks,
    ctr: ctr,
    ecpm: ecpm,
    date: moment().format('YYYY-MM-DD'),
    hour: moment().hour(),
    timestamp: Date.now()
  });
  
  // 保存到数据库
  revenueRecord.save((err) => {
    if (err) {
      console.error('保存广告收益记录失败:', err);
      res.json({ code: 1, message: '上报失败' });
    } else {
      console.log('广告收益记录保存成功:', adPlatform);
      res.json({ code: 0, message: '上报成功' });
    }
  });
});

// 获取广告收益统计 API
app.get('/ad/statistics', (req, res) => {
  const { startDate, endDate, adPlatform, adType } = req.query;
  
  // 构建查询条件
  const query = {};
  if (adPlatform) {
    query.adPlatform = adPlatform;
  }
  if (adType) {
    query.adType = adType;
  }
  if (startDate) {
    query.date = { $gte: startDate };
  }
  if (endDate) {
    query.date = {
      ...query.date,
      $lte: endDate
    };
  }
  
  // 分组统计
  AdRevenueRecord.aggregate([
    { $match: query },
    { $group: { 
      _id: { date: '$date', adPlatform: '$adPlatform', adType: '$adType' },
      totalRevenue: { $sum: '$revenue' },
      totalImpressions: { $sum: '$impressions' },
      totalClicks: { $sum: '$clicks' },
      avgCtr: { $avg: '$ctr' },
      avgEcpm: { $avg: '$ecpm' }
    } },
    { $sort: { '_id.date': 1 } }
  ], (err, result) => {
    if (err) {
      console.error('统计失败:', err);
      res.json({ code: 1, message: '统计失败' });
    } else {
      res.json({ code: 0, data: result });
    }
  });
});

// 获取广告收益趋势 API
app.get('/ad/revenue-trend', (req, res) => {
  const { startDate, endDate, adPlatform } = req.query;
  
  // 构建查询条件
  const query = {};
  if (adPlatform) {
    query.adPlatform = adPlatform;
  }
  if (startDate) {
    query.date = { $gte: startDate };
  }
  if (endDate) {
    query.date = {
      ...query.date,
      $lte: endDate
    };
  }
  
  // 按日期分组统计
  AdRevenueRecord.aggregate([
    { $match: query },
    { $group: { 
      _id: '$date',
      totalRevenue: { $sum: '$revenue' },
      totalImpressions: { $sum: '$impressions' }
    } },
    { $sort: { _id: 1 } }
  ], (err, result) => {
    if (err) {
      console.error('统计失败:', err);
      res.json({ code: 1, message: '统计失败' });
    } else {
      res.json({ code: 0, data: result });
    }
  });
});

app.listen(3000, () => {
  console.log('广告收益统计服务启动,监听端口 3000');
});

案例:实现智能广告管理系统

业务场景

某内容应用希望实现智能广告管理系统,根据用户行为和应用场景自动调整广告展示策略,最大化广告收益。

实现方案

  1. 用户分群

    • 根据用户活跃度、消费能力、地域等特征划分用户群体
    • 为不同用户群体设置不同的广告策略
    • 实现个性化广告投放
  2. 场景识别

    • 识别应用中的不同场景(如启动、浏览、游戏、阅读等)
    • 为不同场景选择合适的广告类型
    • 优化广告展示时机和频率
  3. 智能调度

    • 多广告平台轮询,提高填充率
    • 基于 eCPM 实时调整广告平台优先级
    • 动态调整广告位价格,最大化收益
  4. 效果优化

    • A/B 测试不同广告策略的效果
    • 实时监控广告表现,自动调整策略
    • 预测广告收益,优化资源分配
  5. 反作弊系统

    • 识别和过滤无效点击和曝光
    • 防止广告欺诈,保护广告主利益
    • 维护广告生态的健康发展

跨平台广告集成注意事项

1. 平台差异

  • iOS

    • 需要在 Info.plist 中配置广告相关权限和描述
    • 应用退后台后广告可能会被暂停
    • 隐私政策需要明确说明广告数据的使用
  • Android

    • 需要在 AndroidManifest.xml 中配置广告相关权限
    • 不同 ROM 对广告展示的支持程度不同
    • 部分机型可能会屏蔽广告
  • Web

    • 受浏览器广告拦截器影响
    • 跨域广告请求需要处理 CORS 问题
    • 依赖浏览器环境和网络条件
  • 小程序

    • 每个平台的小程序都有自己的广告机制
    • 广告展示和收益规则受平台限制
    • 需要在小程序后台配置广告相关设置

2. 性能优化

  • 加载优化:广告预加载,避免影响应用性能
  • 内存优化:及时销毁广告实例,避免内存泄漏
  • 网络优化:根据网络环境调整广告类型和质量
  • 电量优化:合理控制广告刷新频率,减少电量消耗

3. 用户体验

  • 广告频率:合理控制广告展示频率,避免过度打扰用户
  • 广告位置:选择合适的广告位置,不影响应用核心功能
  • 广告质量:确保广告内容健康、相关,提高用户接受度
  • 关闭方式:提供清晰的广告关闭方式,尊重用户选择

4. 合规性

  • 隐私政策:遵守各地区的隐私保护法规,如 GDPR、CCPA 等
  • 广告标识:明确标识广告内容,避免误导用户
  • 数据收集:合理收集和使用用户数据,保护用户隐私
  • 广告内容:确保广告内容符合法律法规和平台政策

代码优化建议

1. 广告服务封装优化

将广告相关功能封装成更完善的服务模块,支持多平台和智能调度:

// utils/adService.js
class AdService {
  constructor() {
    this.isInitialized = false;
    this.adInstances = {};
    this.adPlatforms = [];
    this.currentPlatformIndex = 0;
    this.userSegment = 'default';
  }
  
  // 初始化广告服务
  init(config = {}) {
    if (this.isInitialized) return;
    
    this.config = {
      platforms: config.platforms || ['csj'],
      adUnits: config.adUnits || {},
      userSegment: config.userSegment || 'default',
      debug: config.debug || false
    };
    
    this.adPlatforms = this.config.platforms;
    this.userSegment = this.config.userSegment;
    
    // 初始化各平台广告
    this.initAdPlatforms();
    
    this.isInitialized = true;
  }
  
  // 初始化广告平台
  initAdPlatforms() {
    this.adPlatforms.forEach(platform => {
      this.initAdPlatform(platform);
    });
  }
  
  // 初始化单个广告平台
  initAdPlatform(platform) {
    switch (platform) {
      case 'csj':
        // 初始化穿山甲广告
        console.log('初始化穿山甲广告');
        break;
      case 'gdt':
        // 初始化优量汇广告
        console.log('初始化优量汇广告');
        break;
      case 'admob':
        // 初始化 AdMob 广告
        console.log('初始化 AdMob 广告');
        break;
      default:
        console.warn('未知的广告平台:', platform);
    }
  }
  
  // 获取下一个广告平台
  getNextAdPlatform() {
    const platform = this.adPlatforms[this.currentPlatformIndex];
    this.currentPlatformIndex = (this.currentPlatformIndex + 1) % this.adPlatforms.length;
    return platform;
  }
  
  // 创建广告实例
  createAd(adType, options = {}) {
    if (!this.isInitialized) {
      console.warn('广告服务未初始化');
      return null;
    }
    
    // 获取广告平台
    const platform = options.platform || this.getNextAdPlatform();
    
    // 获取广告单元 ID
    const adUnitId = options.adUnitId || this.getAdUnitId(platform, adType);
    if (!adUnitId) {
      console.warn('未配置广告单元 ID');
      return null;
    }
    
    // 创建广告实例
    let adInstance = null;
    switch (adType) {
      case 'banner':
        adInstance = this.createBannerAd(platform, adUnitId, options);
        break;
      case 'interstitial':
        adInstance = this.createInterstitialAd(platform, adUnitId, options);
        break;
      case 'rewarded':
        adInstance = this.createRewardedAd(platform, adUnitId, options);
        break;
      case 'native':
        adInstance = this.createNativeAd(platform, adUnitId, options);
        break;
      default:
        console.warn('未知的广告类型:', adType);
    }
    
    if (adInstance) {
      const key = `${platform}_${adType}`;
      this.adInstances[key] = adInstance;
    }
    
    return adInstance;
  }
  
  // 获取广告单元 ID
  getAdUnitId(platform, adType) {
    const adUnits = this.config.adUnits[platform] || {};
    return adUnits[adType] || adUnits.default;
  }
  
  // 创建横幅广告
  createBannerAd(platform, adUnitId, options = {}) {
    // 实现横幅广告创建逻辑
    console.log(`创建 ${platform} 横幅广告: ${adUnitId}`);
    return {};
  }
  
  // 创建插屏广告
  createInterstitialAd(platform, adUnitId, options = {}) {
    // 实现插屏广告创建逻辑
    console.log(`创建 ${platform} 插屏广告: ${adUnitId}`);
    return {};
  }
  
  // 创建激励视频广告
  createRewardedAd(platform, adUnitId, options = {}) {
    // 实现激励视频广告创建逻辑
    console.log(`创建 ${platform} 激励视频广告: ${adUnitId}`);
    return {};
  }
  
  // 创建原生广告
  createNativeAd(platform, adUnitId, options = {}) {
    // 实现原生广告创建逻辑
    console.log(`创建 ${platform} 原生广告: ${adUnitId}`);
    return {};
  }
  
  // 显示广告
  showAd(adType, options = {}) {
    const platform = options.platform || this.getNextAdPlatform();
    const key = `${platform}_${adType}`;
    const adInstance = this.adInstances[key];
    
    if (adInstance) {
      // 显示广告
      console.log(`显示 ${platform} ${adType} 广告`);
      return true;
    } else {
      // 创建并显示广告
      const adInstance = this.createAd(adType, options);
      if (adInstance) {
        console.log(`创建并显示 ${platform} ${adType} 广告`);
        return true;
      }
    }
    
    return false;
  }
  
  // 销毁广告实例
  destroyAd(adType, platform = null) {
    if (platform) {
      const key = `${platform}_${adType}`;
      delete this.adInstances[key];
    } else {
      // 销毁所有平台的该类型广告
      Object.keys(this.adInstances).forEach(key => {
        if (key.endsWith(`_${adType}`)) {
          delete this.adInstances[key];
        }
      });
    }
  }
  
  // 销毁所有广告实例
  destroyAllAds() {
    this.adInstances = {};
  }
  
  // 更新用户分群
  updateUserSegment(segment) {
    this.userSegment = segment;
    // 根据用户分群调整广告策略
    this.adjustAdStrategy();
  }
  
  // 调整广告策略
  adjustAdStrategy() {
    // 根据用户分群和其他因素调整广告策略
    console.log(`调整广告策略,用户分群: ${this.userSegment}`);
  }
}

export default new AdService();

2. 广告加载和展示优化

优化广告加载和展示逻辑,提高用户体验和广告收益:

// 优化广告加载
loadAd(adType, options = {}) {
  // 检查网络状态
  uni.getNetworkType({
    success: (res) => {
      if (res.networkType === 'none') {
        // 无网络时延迟加载
        setTimeout(() => {
          this.doLoadAd(adType, options);
        }, 3000);
      } else if (res.networkType === '2g') {
        // 2G 网络时加载轻量级广告
        options.lightweight = true;
        this.doLoadAd(adType, options);
      } else {
        // 正常网络时加载广告
        this.doLoadAd(adType, options);
      }
    }
  });
}

// 优化广告展示
tryShowAd(adType, options = {}) {
  // 检查应用状态
  const appState = this.getAppState();
  if (appState !== 'foreground') {
    console.warn('应用不在前台,暂不展示广告');
    return false;
  }
  
  // 检查用户交互状态
  if (this.isUserInteracting()) {
    console.warn('用户正在交互,暂不展示广告');
    return false;
  }
  
  // 检查广告展示频率
  if (!this.checkAdFrequency(adType)) {
    console.warn('广告展示频率过高,暂不展示');
    return false;
  }
  
  // 显示广告
  return this.showAd(adType, options);
}

// 检查广告展示频率
checkAdFrequency(adType) {
  const now = Date.now();
  const lastShowTime = this.lastAdShowTime[adType] || 0;
  const minInterval = this.getMinAdInterval(adType);
  
  if (now - lastShowTime >= minInterval) {
    this.lastAdShowTime[adType] = now;
    return true;
  }
  
  return false;
}

// 获取广告最小展示间隔
getMinAdInterval(adType) {
  const intervals = {
    banner: 30000, // 30秒
    interstitial: 60000, // 1分钟
    rewarded: 120000, // 2分钟
    native: 15000 // 15秒
  };
  
  return intervals[adType] || 30000;
}

章节总结

本章节详细介绍了 uni-app 广告集成的方法和最佳实践,包括:

  1. 核心知识点

    • 广告类型概述和常用平台
    • 广告系统架构和集成方法
    • 广告收益优化和合规性
  2. 实用案例

    • 实现应用广告功能的完整方案
    • 跨平台广告集成的代码实现
    • 后端广告收益统计服务的设计
  3. 跨平台注意事项

    • 各平台广告集成差异和解决方案
    • 性能优化和用户体验
    • 合规性和隐私保护
  4. 代码优化建议

    • 广告服务的封装和智能调度
    • 广告加载和展示的优化
    • 广告策略的动态调整

通过本章节的学习,您应该能够掌握 uni-app 广告集成的方法,实现智能、高效的广告展示和收益管理功能,为应用创造可观的收益。在实际应用中,您可以根据具体需求选择合适的广告平台和策略,不断优化广告效果,提升用户体验和收益水平。

学习建议

  1. 实践练习:搭建一个完整的广告集成系统,包括前端集成和后端统计
  2. 平台测试:在不同平台上测试广告功能,了解平台差异
  3. 收益优化:分析广告数据,优化广告展示策略
  4. 用户体验:关注用户对广告的反馈,平衡收益和体验
  5. 持续学习:关注广告技术的发展和平台政策的更新,及时调整实现方案
« 上一篇 uni-app 数据统计 下一篇 » uni-app 内容管理