主题
引入依赖
文档版本 v1.0.0
本页对应 SDK 1.0.0,与离线包 docs/ 目录里的同一份文档内容一致。其他版本见文档中心。
两种方式二选一:能访问外网 Maven 仓库的用 Maven 方式,内网构建环境用离线包方式。
Maven 方式
配置仓库
项目根 settings.gradle 加入两个仓库,均为公开只读,不需要账号密码:
groovy
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url 'https://admin.maemi.cn/maven/' } // AdMix
maven { url 'https://artifact.bytedance.com/repository/pangle' } // 穿山甲官方仓库(接穿山甲时必需)
}
}优量汇 SDK 在 Maven Central 上,不用另配仓库。
穿山甲仓库不能省
穿山甲 SDK 只发在字节自己的仓库里,Maven Central 上没有。少配这一条的表现是 Could not find com.pangle.cn:mediation-sdk,而不是「广告少一家」。
声明依赖
推荐用「全家桶」聚合坐标,一行:
groovy
dependencies {
implementation "com.admix:sdk:1.0.0" // 聚合核心 + 穿山甲 + 优量汇
}只接哪家就引哪一行,不引的那家连同它的广告 SDK 完全不进包:
| 聚合坐标 | 等价于 | 最小工程包体积(arm64 单 ABI,Release 混淆,实测) |
|---|---|---|
com.admix:sdk:1.0.0 | core + adapter-csj + adapter-gdt | 约 15 MB |
com.admix:sdk-csj:1.0.0 | core + adapter-csj | 约 13 MB |
com.admix:sdk-gdt:1.0.0 | core + adapter-gdt | 约 2.2 MB |
聚合坐标只有一个 pom、不含任何代码,作用是把一组模块的版本收成一个数字。好处有两条:
- 升级时不会漏升其中一个 —— 三个坐标各写一个版本号,漏一个不会报错, 而「core 1.1.0 + adapter-csj 1.0.0」这种组合平台从没验证过
- 平台以后新增一家广告平台,升
com.admix:sdk的版本号就带上了,宿主build.gradle一行不改
也可以逐个引(需要精细控制传递依赖、或用 version catalog 统一管版本时),效果完全一样, 三个版本号必须一致:
groovy
implementation "com.admix:core:1.0.0" // 必需
implementation "com.admix:adapter-csj:1.0.0" // 穿山甲(GroMore 聚合通道),可选,自动带上穿山甲 SDK
implementation "com.admix:adapter-gdt:1.0.0" // 优量汇,可选,自动带上优量汇 SDK适配器带入的广告 SDK
不需要再单独引穿山甲、优量汇的 SDK。 适配器会传递引入以下版本(均为真机验证过的版本):
| 适配器 | 带入的广告 SDK | 仓库 |
|---|---|---|
adapter-csj | com.pangle.cn:mediation-sdk:7.7.1.6 | 穿山甲官方仓库 |
adapter-gdt | com.qq.e.union:union:4.680.1550 | Maven Central |
- 广告 SDK 以 runtime 范围引入:会打进 App,但宿主代码里 import 不到它们的类 —— 宿主只应调用 AdMix 的对外 API
- 上表两个版本被锁死,工程里出现别的版本会直接构建失败,见下一节
- 已有工程里放过穿山甲 / 优量汇 aar 文件(
libs/下)的,要删掉这些文件和对应的implementation files(...),否则会出现重复类编译错误 core会带入androidx.annotation(纯注解包,不进 dex,引了 AndroidX 的工程本来就有)
广告 SDK 的版本锁定
为什么要锁
适配器里的取价、竞价回传、各回调的时序,都是照某一个广告 SDK 版本的实测行为写的。 版本被换掉之后既不报错也不崩,典型表现是「Release 混淆包下某个广告位就是不出广告」—— 端上日志正常、平台后台也正常,只有填充率悄悄掉下去。
Gradle 默认的「版本冲突取高版本」恰好让这件事静默发生:宿主工程自己引了穿山甲 SDK、 或某个三方库间接依赖了它,适配器就跑在了没验过的版本上。所以这件事被提到构建期暴露。
冲突时的报错
两个适配器在自己的 Gradle 元数据里把广告 SDK 声明成 strictly 严格版本约束 (implementation 侧与 dependencyConstraints 侧各一份,分别卡住运行时类路径和编译类路径), 并带上说明文字。工程里出现别的版本时构建失败:
text
> Could not resolve all files for configuration ':app:releaseRuntimeClasspath'.
> Could not resolve com.pangle.cn:mediation-sdk:7.8.0.
Required by:
project :app
> Cannot find a version of 'com.pangle.cn:mediation-sdk' that satisfies the version constraints:
Dependency path 'MyApp:app:unspecified' --> 'com.pangle.cn:mediation-sdk:7.8.0'
Dependency path 'MyApp:app:unspecified' --> 'com.admix:sdk:1.0.0' (runtime)
--> 'com.admix:adapter-csj:1.0.0' --> 'com.pangle.cn:mediation-sdk:{strictly 7.7.1.6}'
because of the following reasons: 【AdMix 锁定版本】adapter-csj 只在穿山甲 SDK 7.7.1.6 上
做过真机 + Release 混淆包验证,顶高 / 压低都可能让某个广告位静默不出广告。正确做法:把冲突那一行去掉。查是谁把版本带进来的:
bash
./gradlew :app:dependencyInsight --configuration releaseRuntimeClasspath --dependency mediation-sdk确实需要升级广告 SDK 时联系平台。平台在新版本上跑完三种广告位的真机 + Release 混淆包验证、 更新 -dontwarn 规则、发布新版适配器,宿主只升 AdMix 的版本号。
临时强制覆盖
赶时间、平台还没来得及发新版时可以在 App 模块里写:
groovy
// 绕开 AdMix 的版本锁定,出问题请先改回来再报障
configurations.all {
resolutionStrategy {
force 'com.pangle.cn:mediation-sdk:7.7.1.6' // 换成需要的版本
}
}resolutionStrategy.force 的优先级高于严格约束,依赖解析会照常通过(已实测)。
强制覆盖的三条风险
- 该版本未经平台验证,最可能的表现是某个广告位不出广告,而不是崩溃或报错
- R8 混淆包很可能编不过:随 aar 带的
-dontwarn是按锁定版本生成的。 实测把穿山甲强制降到7.6.4.3后,R8 报Missing class android.os.SystemProperties等一串缺失类,Debug 包则能正常打出来。要继续用就得把 R8 提示的missing_rules.txt内容补进宿主的proguard-rules.pro - 报障前请先去掉
force、换回锁定版本复现一次
运行时再核一次
严格约束只对 Gradle 消费者生效 —— Maven 工程、离线 aar 方式、以及上面的 force 都绕得过去, 所以 AdMix.init() 里会读取广告 SDK 的实际版本与锁定版本比对,不一致时打一条 warn (只告警,不阻断,广告照常跑),并随拉配置与埋点上报给平台:
text
W/AdMix: adapter 就绪: csj (ADN SDK 7.6.4.3) ⚠️ 版本与 adapter 锁定的 7.7.1.6 不一致 ——
adapter 只在 7.7.1.6 上做过真机验证,当前版本下可能某个广告位静默不出广告。…接入后先看一眼这行日志是 I 级还是 W 级。
按需集成单家广告平台
SDK 不在代码里写死「支持哪几家」—— 每个适配器通过 Java SPI (META-INF/services/com.admix.adapter.IAdnAdapter)自己声明身份,core 启动时扫描一遍, 引了谁就发现谁。由此:
- 只引
adapter-csj的包里根本不存在优量汇的声明,不是「跳过一家」,而是那一家不存在。 不会崩、不报错 - 拉配置时 SDK 会把实际发现的适配器列表报给平台,服务端据此把未集成的广告平台从下发的配置里摘掉。 日志里能看到
拉取远端配置 … adapters=[csj]与远端配置加载完成,ADN: [csj] … 服务端按本机能力裁掉: gdt - 不需要写
packagingOptions/packaging { resources { merges … } }:AGP 默认就把META-INF/services/**合并而不是取其一,混淆规则也随 aar 自动生效
自定义打包策略时不要排除 META-INF/services
排掉之后 SDK 发现不了任何适配器,日志会打 没有发现任何 adapter,一条广告都不会有, 而构建完全正常。
平台以后新增一家广告平台(美团 / 京东 / 快手 / 汇川等):用全家桶坐标的话升个版本号就带上了; 逐个引的话多引一个 com.admix:adapter-xxx 坐标。两种方式下 core 都不需要单独升级、 业务代码一行不改。
离线包方式
从开发者后台「接入指引」页下载,或直接下载 https://admin.maemi.cn/maven/downloads/admix-android-sdk-1.0.0.zip。
包内是三个 AdMix aar 加全套文档,不含穿山甲、优量汇的 SDK 文件 (两家的开发者协议不允许第三方转发),需要自行从穿山甲后台 / 优量汇开发者平台下载 上表所列的同一版本。本地 aar 不会带出传递依赖,core 依赖的 androidx.annotation:annotation:1.3.0 要手动声明。具体步骤见包内 README.md。
离线方式下没有聚合坐标,也没有版本锁
本地 aar 不带依赖元数据,两家广告 SDK 的版本只能人工对齐。装错版本不会在构建期报错, 只能靠启动日志里那行 adapter 就绪: … 是不是带告警来发现。
清单合并冲突
穿山甲、优量汇的 SDK 清单里都写了 <application> 属性(穿山甲 allowBackup="true"、 label="@string/app_name",优量汇 allowBackup="false"),同时接两家时 Gradle 合并清单会报 Attribute application@allowBackup ... is also present at 一类错误。
宿主的 <application> 上显式写出自己的值并用 tools:replace 覆盖即可:
xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> <!-- tools 命名空间别漏了 -->
<application
android:allowBackup="false"
android:label="@string/app_name"
tools:replace="android:allowBackup,android:label">
...
</application>
</manifest>android:label 只在宿主的 label 与 @string/app_name 不同名时才冲突;不冲突就从 tools:replace 里去掉它。报错信息会指名是哪个属性,照着加即可。
还需要在清单里移除两项权限,来源与作用见《合规与隐私》「申请的权限及用途」:
xml
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:node="remove" />
<uses-permission android:name="com.android.permission.GET_INSTALLED_APPS" tools:node="remove" />ABI 与混淆
ABI 建议只保留两种,可显著减小包体积:
groovy
defaultConfig {
ndk { abiFilters 'arm64-v8a', 'armeabi-v7a' }
}混淆规则已随 aar 自动生效(consumer-rules.pro),接入方无需额外配置, proguard-rules.pro 里不用加任何 -keep。minSdk 29 + R8 的外部最小工程实测零缺失类告警。
Release 混淆包必须单独验证一次,判据与排查命令见《常见问题》「Release 混淆包没有广告」。