主题
常见问题
文档版本 v1.0.0
本页对应 SDK 1.0.0,与离线包 docs/ 目录里的同一份文档内容一致。其他版本见文档中心。
按现象组织。错误码逐条对照见《错误码参考》。
接入自检清单
跑起来后逐条核对,全部通过再提交测试。
bash
adb logcat -s "AdMix:V"| # | 核对项 | 通过的标志 | 不通过怎么办 |
|---|---|---|---|
| 1 | 适配器被发现了,且广告 SDK 版本对得上 | 启动日志里每个引入的适配器一行,且是 I 级:adapter 就绪: csj (ADN SDK 7.7.1.6) / adapter 就绪: gdt (ADN SDK 4.680.1550) | 出现 没有发现任何 adapter → 坐标没引全,或打包策略把 META-INF/services/** 排除了。这一行变成 W 级并带「版本与 adapter 锁定的 … 不一致」→ 工程里的广告 SDK 被换成了未验证的版本,见《引入依赖》「广告 SDK 的版本锁定」 |
| 2 | 同意之前不联网 | 停在隐私弹窗时 adb shell run-as <包名> ls files/ 为空,且没有 /v1/config 请求 | start() 被提前调了,挪到「同意」之后 |
| 3 | 能拉到配置 | 远端配置加载完成,ADN: [csj, gdt] …,且 start() 回调 onSuccess | 见《配置与凭证》「拉不到配置的排查」 |
| 4 | 能力上报正确 | 拉取远端配置 … adapters=[csj,gdt] 与实际引入的适配器一致 | 只引一家时应只有那一家;对不上说明依赖引错 |
| 5 | 三种广告位都能出广告 | 每种至少一次 最终胜出: xxx,并在屏幕上看到广告 | 见《错误码参考》 |
| 6 | 埋点有上报 | 请平台运营在后台「数据报表」按 AppID 查当天,能看到请求 / 填充 / 曝光 | 确认 start() 已调、设备联网;AdMix.flushEvents() 可催一次 |
| 7 | 开屏五条路径都能进主页 | 手动测:正常展示后关闭 / 点广告再返回 / 飞行模式无填充 / 展示中断网,都能进主页 | 兜底定时器没装齐,见《开屏广告》「兜底放行」 |
| 8 | Banner 刷新后仍正常 | 停在 Banner 页 2~3 个刷新周期,无空白、无闪烁、内存不持续上涨 | onDestroy 漏了 destroy() |
| 9 | Release 混淆包也验过 | 用 minifyEnabled true 的包重跑第 1、5、8 条 | 见下方「Release 混淆包没有广告」 |
| 10 | 上线包关掉 debug | AdMixConfig.Builder().debug(false) | — |
第 9 条不能省
Debug 能跑不代表 Release 能跑。 适配器自注册与反射实例化在混淆 / 打包合并下可能静默失效, 表现是「一条广告都没有」而不是崩溃。
构建期失败
| 报错关键字 | 原因 | 怎么办 |
|---|---|---|
Cannot find a version of 'com.pangle.cn:mediation-sdk' that satisfies the version constraints + 【AdMix 锁定版本】 | 工程里另有一处引了穿山甲 SDK 的别的版本 | 见《引入依赖》「广告 SDK 的版本锁定」。用 ./gradlew :app:dependencyInsight --configuration releaseRuntimeClasspath --dependency mediation-sdk 查是谁引进来的 |
同上,模块是 com.qq.e.union:union | 同上,优量汇侧 | 同上 |
Attribute application@allowBackup ... is also present at | 两家 SDK 的 <application> 属性冲突 | 见《引入依赖》「清单合并冲突」 |
Could not find com.pangle.cn:mediation-sdk | 少配了穿山甲官方仓库 | 见《引入依赖》「配置仓库」 |
Missing class okhttp3.* / Missing class com.bytedance.*(R8) | 广告 SDK 版本被 force 成了锁定之外的版本,随 aar 带的 -dontwarn 对不上 | 去掉 force 换回锁定版本;确需保留就把 R8 生成的 missing_rules.txt 内容补进 proguard-rules.pro |
Duplicate class com.bytedance… / com.qq.e… | libs/ 下还留着广告 SDK 的 aar,或工程里另行声明了同一个 SDK | 删掉 libs/ 里的文件和对应的 implementation files(...) |
两条 lint Error 与两类构建 Warning
assembleRelease / lintVital 不受影响,能正常打包(minSdk 29 + R8 的最小工程已实测)。 只有显式跑 ./gradlew lint 时会报这两条 Error:
| lint 检查 | 报什么 | 为什么不用处理 |
|---|---|---|
NotificationPermission | 「targeting Android 13+ 时发通知需要 POST_NOTIFICATIONS(usage from com.byazt.bd.v)」 | com.byazt.* 是穿山甲 SDK 内部的类。为第三方 SDK 的内部行为向用户多要一个运行时权限并不合理,AdMix 也没有声明它 |
QueryAllPackagesPermission | 「应该用 <queries> 而不是 QUERY_ALL_PACKAGES」 | 宿主清单里恰恰是在移除这个权限(tools:node="remove"),但 lint 只看到清单里出现了这个权限名,识别不了 remove |
工程有 lint { abortOnError true } 或把 lint 接进 CI 时,把这两条降级即可 (其余检查不要放松):
groovy
android {
lint {
warning 'NotificationPermission'
warning 'QueryAllPackagesPermission'
}
}另外构建时会有一条 manifest Warning uses-permission#com.android.permission.GET_INSTALLED_APPS was tagged ... but no other declaration present 和若干条穿山甲 aar 自身的 D8 Expected stack map table 警告 —— 两者都正常,不需要处理。 前者恰好证明没有任何 SDK 声明 GET_INSTALLED_APPS(华为是在运行时自己加的)。
完全没有广告
按这个顺序排查:
start()到底调了没有? 调用时机在「同意隐私政策」之后吗 —— 没调就一定拉不到配置- 日志里有
远端配置加载完成吗? 没有就按《配置与凭证》「拉不到配置的排查」对号 - 有
adapter 就绪吗? 一行都没有就是依赖没引全或打包策略排除了META-INF/services/**,见《引入依赖》 - 拿到的错误码是什么? 对照《错误码参考》
- 配置拉到了但某家广告平台不在里面 → 看日志里的
服务端按本机能力裁掉: gdt, 说明没引那家的适配器,服务端按上报的能力主动摘掉了。这是正常机制,不是故障
Release 混淆包没有广告
先跑这一条,10 秒定位:
bash
unzip -p <release apk 路径> META-INF/services/com.admix.adapter.IAdnAdapter| 输出 | 结论 |
|---|---|
com.admix.adapter.csj.CsjAdapter + com.admix.adapter.gdt.GdtAdapter(各一行) | 声明正常,问题不在这里 → 看日志的 adapter 就绪 与错误码 -1005 |
| 只有一行 / 空 / 文件不存在 | 打包策略把 META-INF/services/** 吃掉了 → 去掉 packagingOptions / packaging.resources 里对它的 exclude 或 pickFirst |
混淆规则随 aar 自动生效,不需要为 AdMix 写任何 -keep。
开屏白屏、页面永远不关
兜底定时器没装齐。开屏必须有三段不依赖任何回调的兜底放行,见《开屏广告》「兜底放行」。
SDK 侧已修了优量汇「命中缓存时容器尚未布局就展示」这一具体成因, 但下一个广告平台、下一个版本还会有别的成因 —— 兜底仍然必须有。
开屏一直是实时请求,缓存没命中
真正的冷启动(新进程)第一条开屏一定是实时请求。 缓存池只在进程内存里, 进程被杀后清空。缓存命中发生在热启动开屏、返回桌面后再从图标进入、下一次激励视频等场景。
详见《预加载与缓存》「进程被杀后缓存清空」。
Banner 刷新后看着没变
测试广告位的素材池小且风格雷同,肉眼看着像没变,实际已经换了一条。 用刷新计数(onAdLoaded 回调次数)确认,不要靠肉眼。
Banner 页退出后内存持续上涨
onDestroy 漏了 bannerAd.destroy()。Banner 长期持有 Activity 引用且定时器一直在转, 不销毁的后果是内存持续上涨 + 曝光数虚高。
激励视频点「跳过」没有关闭
穿山甲会先弹挽留弹窗「再看一个获取更多奖励 / 坚持退出」,点「坚持退出」才触发 onAdClose。 优量汇点关闭同样会弹挽留弹窗。业务侧不要假设「点跳过 == 广告结束」。
视频播完了但 onReward 没触发
onReward 与 onVideoComplete 是两件事。实测优量汇的激励条件可能是「打开 App 体验 15 秒」 或「点击广告」,只播完视频 onReward 不触发;反过来也实测到过 onReward 发了而 onVideoComplete 一次都没回调。
业务判据只能是 onReward,详见《激励视频广告》。
华为弹「读取已安装应用列表」
来自优量汇(不是穿山甲),已修复并两轮真机验证通过。若仍出现, 把系统日志和时间点交给平台。完整结论与遗留项见《合规与隐私》「应用列表读取」。
包体积偏大
| 引入方式 | 最小工程包体积(arm64 单 ABI,Release 混淆,实测) |
|---|---|
com.admix:sdk(两家都接) | 约 15 MB |
com.admix:sdk-csj(只接穿山甲) | 约 13 MB |
com.admix:sdk-gdt(只接优量汇) | 约 2.2 MB |
两条可做的:只引实际要接的那一家;用 abiFilters 只保留 arm64-v8a 与 armeabi-v7a。
报表与自己统计的对不上
统计口径不同:平台报表统计 SDK 侧的请求 / 曝光事件,各广告平台按自己的计费口径统计, 5~10% 的差异属正常。
另有两条缓存指标的口径容易被误读(缓存命中率的分母是曝光不是请求、过期浪费数是下限), 见《数据与事件》「报表口径」。
日志里价格和广告位 ID 显示 ***
刻意如此,与 debug 开关无关 —— logcat 对宿主开发者可见,这两项不对接入方开放。 需要定位到具体广告位时,把广告位标识、广告平台和时间点交给平台运营查询。
找谁要什么
| 需要的东西 | 从哪拿 |
|---|---|
| SDK(Maven 方式) | 根 settings.gradle 配 https://admin.maemi.cn/maven/ 与穿山甲官方仓库,引 com.admix:sdk:1.0.0 一行 |
| SDK(离线包) | https://admin.maemi.cn/maven/downloads/admix-android-sdk-1.0.0.zip,或开发者后台「接入指引」页 |
| 全套文档 | 离线包 docs/ 目录,或开发者后台「接入指引」页 |
| AppID、App 密钥 | 平台运营(后台「应用管理 → 接入」) |
| 广告位标识列表 | 平台运营(后台「广告位管理」)。Banner 记得同时确认尺寸规格 |
| AppSecret(只给服务端) | 平台运营,只显示一次 |
| 报表 / 填充率 / 收益 | 开发者后台自己看(运营开账号) |
| 改价格、调瀑布顺序、开关广告位 | 平台运营在后台改,接入方不用发版 |