安卓修改大师智改工坊 · 技术教程

电脑版去自家应用开屏广告与弹窗:需求写法与验收

工具:安卓修改大师电脑版 官网:https://www.apkeditor.cn/ai-version.aspx

只需说话,就能让应用变成你想要的样子

这篇教程只讨论一种场景:应用是你自家的,或者你已经拿到明确授权,可以改动它的启动流程和运营弹窗。我们要做的不是“把广告干掉”这种模糊动作,而是把“自家开屏推广页不展示、自家活动弹窗不弹出、该留的合规提示一个不少”写成一段机器能执行、你自己能验收的需求,然后交给安卓修改大师电脑版去完成反编译、修改、回编、对齐、签名和安装预览。

“去广告”这三个字在安卓改包领域很容易被混用。有人指的是自家 App 里那张活动开屏图,有人指的是第三方广告 SDK 的库存,还有人想绕过授权、去掉付费内容。这三件事的性质完全不同,处理方式也完全不同。本文只碰第一类,也就是你有自有版权或已获授权、纯粹由自己团队投放和运营的页面与弹窗。第二类要先看合同和授权范围,第三类不在本文讨论范围,也请勿用于破解或绕过安全机制。

一、先划边界:只处理自家或已授权应用的自家运营位

很多团队搜索“安卓去开屏广告”,实际上把三种需求搅在了一起。第一种是自家运营位:自家活动开屏页、自家公告弹窗、自家更新提示、自家拉新引导。这些东西的图片、文案、跳转链接、投放开关都在自己手里,删掉或关掉不涉及别人的权益。第二种是第三方广告变现:广告 SDK 的库存、填充、结算受合同约束,哪怕代码在你包里,也不等于你可以随手删。第三种是破解、去授权、去除付费内容,这类操作会绕过安全机制,既不符合工具的使用边界,也可能带来法律风险。

所以动手之前,先把需求归到下面这张表里。只要有一栏对不上,就停下来确认授权,不要用“先改了再说”的方式推进。尤其是外包项目、代理运营项目、收购来的应用,代码在手不代表版权和处置权都在手,最好让法务或业务负责人给一句书面确认,再进入技术流程。

具体场景 是否属于本文范围 判断依据
自家电商或展示类 App 的自家活动开屏页 是 图片、文案、活动链接均为自家资产,有自有版权或已获授权
自家内部工具的更新提示弹窗、活动推广弹窗 是 内部工具由自己团队开发和分发,改动经过负责人同意
第三方广告联盟提供的开屏、插屏、激励视频 否 涉及广告合同与结算,先确认授权范围,不要直接删
他人商业应用去广告、去弹窗 否 没有处置权,请勿用于破解或修改他人产品
去除授权校验、付费内容、会员限制 否 属于绕过安全机制,本文不提供任何做法

安卓修改大师电脑版是运行在 Windows 10/11 64 位系统上的桌面工具,需要 .NET Framework 4.6.2 或更高版本。把 APK 拖进去之后,它会完成反编译、按需求改代码和资源、回编、对齐、签名、校验,还能自动装到手机或模拟器里预览。它负责执行,不负责判断广告归属。也就是说,工具越自动,需求越要写清楚,否则它只能按字面意思猜你的意图。

把“去广告”翻译成工程语言,通常落在三个动作上:删掉某个启动跳转,关掉某个弹窗触发,改掉某个配置开关。与此同时,还要明确哪些东西不能动,比如隐私政策弹窗、权限申请、强制更新、登录态校验、崩溃上报。只有把“删什么、留什么、怎么验收”三件事同时写进需求,才是一次可交付的修改,而不是一次碰运气的尝试。

先记住一句话

本文里的“去广告”,指的是去掉自家或已获授权应用中的自家运营位,不包含破解、去授权、去第三方付费内容,也不包含绕过任何安全机制。请勿把下面的方法套用到你没有处置权的应用上。

二、第一步:确认广告归属和触发时机

同一个视觉页面,可能是启动页,也可能是开屏页,还可能是首页上的一个浮层。名字叫错,需求就会写错,最后要么删出一块白屏,要么把启动初始化一起删掉。确认归属和触发时机,是整个流程里最值得花时间的一步。建议拿一张纸或一个表格,把“谁、在什么时候、因为什么条件、展示了什么、点了之后去哪里”这五件事逐条记下来。

第一件事是核对包名和签名。打开命令行,用 aapt 读应用信息,用 apksigner 读签名证书,确认这个 APK 确实是你家的构建产物,而不是同名换皮包、渠道包或者别人二次打包的版本。包名、版本号、签名摘要三项都要对得上,任何一项对不上就停止操作。

aapt dump badging app-release.apk
apksigner verify --print-certs app-release.apk

第二件事是录屏和截图。至少做三次冷启动,记录每次从点击图标到首页可交互的时长、开屏页停留时长、有没有倒计时和跳过按钮、跳过按钮在什么位置、页面底部有没有自家品牌或活动标识。然后再做两次热启动:按 Home 回到桌面,再从最近任务切回来,看看开屏页是否再次出现。很多“广告”只在冷启动出现,很多“广告”却是在每次回到前台时重新加载,两者的处理点完全不同。

第三件事是抓当前 Activity。启动应用后立刻执行命令,看前台到底是哪个页面。如果开屏页是独立 Activity,通常会看到一个带 Splash、Ad、Welcome、Launch 之类命名的组件;如果开屏内容只是同一个 Activity 里切换的 View,那么前台 Activity 仍然是启动页,只是布局里多了一个广告容器。这个区别会直接影响需求里的“范围”怎么写。

adb shell am start -W -n com.example.ownapp/.ui.LauncherActivity
adb shell dumpsys activity activities | findstr mResumedActivity
adb logcat -c
adb logcat -d | findstr /i "splash ad activity"

第四件事是断网和弱网测试。把设备切到飞行模式,再冷启动一次。如果开屏页变成一个本地品牌图,说明它是网络加载的运营位,并且有兜底;如果直接白屏几秒,说明兜底逻辑本身也有问题,需求里要顺手写上“无网络时直接进入首页,不等待广告请求”。如果断网后开屏页仍然完整出现,那它大概率是本地打包进去的静态资源,处理方式又不一样。

第五件事是查自家配置。很多运营位并不是写死在代码里的,而是由远程配置或功能开关控制,比如活动开关、弹窗频率、版本区间、人群标签。能通过配置关掉的,优先改配置,不要动代码;必须改代码的,再把配置键、默认值和回退逻辑一起写进需求。这里要注意,配置键名要以自己项目的实际代码为准,不要凭印象编一个英文单词塞给 AI。

第六件事是把触发时机列全。下面这张表可以直接拿去对照。触发点不同,验收用例就不同;只测冷启动,往往会漏掉从后台返回、从推送进入、从深链进入这几种路径。

触发时机 典型现象 验证方法 需求里的写法
冷启动 进程被杀后重新打开,先看到全屏活动图 强制停止后点图标启动,重复三次 冷启动不展示自家活动开屏页,直接进入首页
热启动 按 Home 再切回,开屏页又出现一次 Home 键、最近任务、返回键各测两次 从后台返回不重新展示开屏页
首次安装 同意隐私政策后立刻弹出活动页 清除应用数据后重新走首次启动 首次安装、同意隐私政策后也不展示该活动页
每日首次 一天只弹一次,隔天又弹 改系统日期,或等第二天再测 若保留提示,同一天只允许出现一次
版本变化 升级后首次启动弹更新或活动提示 覆盖安装新版本后启动 升级后的首次启动按新规则执行
推送或深链 从通知或网页跳进来,先过一层开屏 用 adb 发送 VIEW 意图打开指定链接 从推送、深链进入时直接到目标页,不插播开屏
网络回调 广告加载慢,首页被压住好几秒 飞行模式、限速网络各测一次 无网络或请求超时时不等待,直接进首页
记录自家应用冷启动与开屏页触发时机

先把冷启动、热启动、推送进入等触发路径逐条记录,再决定改哪里

做到这里,你手里应该有一份“证据包”:三张冷启动截图、一段录屏、几条 logcat、版本号和签名摘要、前台 Activity 名称、用到的配置键、断网表现。没有这份证据包,后面写出来的需求很容易变成“把那个广告弄掉”,AI 只能猜,你也很难验收。把证据留好,后面附件系统正好用得上。

三、第二步:备份原包与建立可回退基线

修改之前先保证能回去。这一步听起来笨,但它是后面敢动手的前提。原包、签名材料、版本信息、设备基线,四样东西缺一样,出问题时就只能靠回忆。尤其是签名,很多人只备份了 APK,没备份 keystore 和口令,等到要发更新时才发现装不上去,那才是最麻烦的情况。

建议把原始 APK 单独放在一个只读目录,文件名带上版本号和日期,例如 ownapp-release-1.8.0-20261021.apk。不要用“final”“new”“改好的”这种命名,过两周你自己也分不清哪个是原始包。原始包只读保存,所有修改都在项目副本里进行,任何一次回退都以它为准。

certutil -hashfile ownapp-release-1.8.0-20261021.apk SHA256
aapt dump badging ownapp-release-1.8.0-20261021.apk
apksigner verify --print-certs ownapp-release-1.8.0-20261021.apk
adb shell dumpsys package com.example.ownapp | findstr versionName

签名材料的备份要单独说。把 keystore 文件、别名、口令、有效期记录在密码管理器里,至少两份异地备份。需求文本和附件里不要出现口令,也不要把 keystore 传给任何人。安卓修改大师电脑版在签名时通过环境变量读取口令,不把口令拼进命令行和日志,这一点对团队协作很重要;你自己整理材料时也应该遵守同样的原则。

备份项 具体做法 缺失后的后果
原始 APK 只读目录保存,文件名含版本与日期,不覆盖 改坏后无法回到可用版本
SHA-256 用 certutil 计算并记入台账 无法判断文件是否被替换或损坏
签名密钥 keystore、别名、口令、有效期存入密码管理器 无法覆盖安装,老用户无法平滑升级
签名摘要 用 apksigner verify 打印证书指纹并截图 改完后无法确认还是同一把钥匙
版本信息 记录 versionCode、versionName、minSdk、targetSdk 验收时说不清改的是哪一版
设备基线 原包安装后的截图、冷启动耗时、logcat 改完后没有对照,无法判断是否变慢
测试账号 准备可清数据的测试账号,不使用真实用户账号 清除数据后无法回到登录态,测试中断

安卓修改大师电脑版给每个项目建一个 8 位随机目录,里面写 config.ini、history.ini,复制一份 source.apk,反编译结果放在 apktool 目录,日志是 apktool.log。这个 source.apk 就是项目内的基线,不要手动去改它。要重新来一次,重新导入原包建项目即可;要对比改动,直接看项目目录里的 apktool 工程和日志。项目多了以后,建议在项目名里带版本号,避免两三天后分不清哪个项目对应哪次需求。

最后确认一下设备基线。用原包安装一次,记录冷启动到首页可点击的大致时间、首页第一屏的样子、隐私弹窗出现的位置、登录后的默认页。改完之后还要用同一台设备、同一网络、同一账号对照。不要拿模拟器的结果去对比真机,也不要用 Wi-Fi 下的结果去对比弱网环境,那样得出的结论没有意义。

四、第三步:把需求写成四要素

需求写不清楚,AI 只能按字面意思猜。你说“把开屏广告去掉”,它可能把启动页一起删了;你说“更新弹窗太烦”,它可能把强制更新和隐私提示也关了。要避免这种结果,最稳的办法是固定成四要素:目标、范围、边界、验收。四个要素分别回答四个问题:改完要达到什么可观察的结果?只允许改哪些页面、类和资源?哪些东西绝对不能动?我凭什么判定这次修改通过?

要素 回答的问题 写法要点 常见反例
目标 改完看到什么、不再看到什么 用可观察的行为描述,一条需求只写一个主目标 “把广告优化一下”“让启动更快”
范围 允许改哪些文件、组件、资源、配置 写包名、版本、Activity、布局、资源名、配置键;不确定的写定位线索 “整个 App 里相关的都改改”
边界 哪些行为和内容必须原样保留 列保留清单,列出禁止动作;宁可保留空壳,不要误删入口 只说“别改坏”,没有具体保留项
验收 用什么操作、看什么结果判定通过 写成测试用例:入口、操作、预期;包含反例和回归项 “我打开看看没问题就行”

目标要写成“行为变化”,不要写成“感觉变化”。“冷启动时不再出现全屏活动图,初始化完成后直接进入首页”是可观察的;“开屏更清爽”不是。目标里最好带上触发路径,因为同一个页面在冷启动、热启动、推送进入时的表现可能不同。只写“冷启动不展示”,测试人员就不会去测从后台返回,最后线上仍然会冒出来。

范围要写到“可定位”的程度。最理想的是包名、版本号、Activity 全名、布局文件名、资源名、配置键都写全,再加一句“只允许修改上述链路涉及的文件”。如果你不知道类名,不要编,改为描述用户路径和证据:“点击图标后先显示 LauncherActivity,约一秒后进入 SplashAdActivity,再进入 MainActivity,logcat 和截图见附件,请先在项目中定位这两个页面及其调用点。”这样 AI 有线索,你也没有伪造事实。

边界是四要素里最容易被忽略、却最能防止事故的一项。把必须保留的东西逐条列出来:隐私政策与用户协议、权限申请与说明、登录态恢复、配置初始化、崩溃上报、推送令牌、深链路由、支付与授权校验、无障碍支持。再列出禁止动作:不新增第三方 SDK,不改网络接口地址,不改包名和版本号,不删除仍在使用的权限声明,不更换签名密钥。边界写得越具体,误删的概率越低。

验收要写成“别人拿着这段话就能执行”的测试用例。每条包含入口、操作、预期结果,最好再附上检查命令。比如“强制停止应用后点图标启动,连续五次,均不出现活动图,首页可点击”,这就是可执行的;“启动正常”则不是。验收里还要有回归项:首次安装同意隐私政策后仍能正常进入、低于最低支持版本时仍强制更新、断网时没有白屏、签名校验通过。只测“广告没了”,很容易把别的东西一起测没了。

需求模板:可以直接改成自己的版本

目标:冷启动与从后台返回时,不再展示自家活动开屏页;保留本地品牌启动图,初始化完成后直接进入首页,不等待活动图网络请求。

范围:应用包名 com.example.ownapp,版本 1.8.0;只处理 LauncherActivity 到 SplashAdActivity 的启动链路、SplashAdActivity 的倒计时与预加载逻辑、配置键 splash_promo_enabled;不改首页、不改包名、不改版本号。

边界:保留隐私政策与权限申请;保留登录态恢复、配置初始化、崩溃上报;不删除 SplashAdActivity 类本身,先移除启动链路中的调用并保留空壳;不新增 SDK,不改网络地址,不更换签名。

验收:强制停止后冷启动五次不出现活动图;Home 后切回三次不出现;飞行模式下不白屏;首次安装同意隐私政策后仍能进入首页;低于最低支持版本时仍强制更新;apksigner verify 通过;logcat 无崩溃与 ActivityNotFound。

一条需求只做一件事。把“去活动开屏”和“改更新弹窗”拆成两轮,不要一次全塞进去。拆开的好处很实际:改动范围小,出问题时容易定位;每一轮都能单独回编、安装、验收;history 里也留下清晰的两条记录,过几天回来还能看懂当时改了什么。反过来,一次提十个改动,最后某个页面白屏,你根本不知道是哪一条引起的。

需求长度不是越长越好。一般情况下,四要素加上定位信息,三百到六百字就足够;复杂项目可以到一千字,但不要粘贴整份源码。真正有价值的是“可观察的目标、可定位的范围、明确的保留项、可执行的验收”,而不是形容词。写完之后自己读一遍,问三个问题:AI 看完能不能找到地方?改完我能不能判断对错?改坏了能不能退回去?三个都能回答“能”,这段需求才算合格。

把去广告需求拆成目标范围边界验收四要素

目标、范围、边界、验收四段写全,后面的修改和测试才有依据

五、自家开屏页与启动页的区别:删错一个就白屏

这是整个流程里最容易混淆的一对概念。启动页解决的是“冷启动那一小段时间里屏幕显示什么”,目的是遮盖白屏、展示品牌、完成初始化;开屏推广页解决的是“用全屏内容换一次曝光”,目的是投放自家活动或广告。两者可以长得几乎一样,都是全屏图片,都有品牌 Logo,但它们的职责、生命周期和删除风险完全不同。

对比维度 启动页 自家开屏推广页 首页
主要职责 遮盖冷启动白屏,完成初始化与品牌露出 展示自家活动、公告或推广内容 承载应用主功能与内容
内容来源 本地资源、主题背景、少量品牌文案 本地打包或自家 CDN 的活动图,可能带跳转链接 接口数据、本地缓存、用户内容
倒计时与跳过 通常没有,初始化完成就离开 常见三秒或五秒倒计时,右上角有跳过 没有
展示时机 冷启动,进程创建后立即显示 初始化后、首页前;有的热启动也展示 启动完成后常驻
删除风险 删掉入口或主题会导致白屏、启动变慢、ActivityNotFound 删掉通常就是本次目标,但要注意同页初始化逻辑 绝不能被开屏需求波及

很多应用把两者做在同一个 Activity 里:启动页 Activity 先显示品牌背景,同时在后台请求活动图,请求成功后把品牌图换成活动图,再开始倒计时。这种情况下,前台 Activity 一直是同一个,你不能把整个 Activity 从清单里删掉,只能删掉活动图的容器、倒计时和网络请求,把“显示品牌图并继续初始化”的逻辑留下。判断方法很简单:如果前台 Activity 的名字从启动到首页都没有变化,基本就是同页切换。

另一种常见做法是独立 Activity:启动页 Activity 完成初始化后,用 startActivity 跳到开屏 Activity,开屏页倒计时结束再跳首页。这种结构在清单里能看到两个 Activity,跳转链清晰,需求可以写“移除从启动页到开屏页的跳转,保留开屏页类作为空壳,确认无其他引用后再决定是否清理”。注意不要一上来就删类,先断开调用,编译通过、运行通过,再考虑清理资源,这样回退成本最低。

还有一种是广告 SDK 的开屏能力:初始化 SDK 后直接调用展示接口,页面由 SDK 渲染,倒计时和跳过按钮也是 SDK 的。本文只处理自家运营位,所以更常见的是自家活动页自己实现。如果你确实要动第三方 SDK,请先回到第一节,确认合同和授权,不要在技术层面替业务做决定。

实例一:自家电商 App 的自家活动开屏页

某团队的自家电商 App 每次冷启动都会展示一张三秒活动图,图片来自自家 CDN,点击后打开自家活动 H5,右上角有跳过。最近活动结束,运营不想再挂这张图,但首页和品牌启动页要保留。这个需求看起来是“把开屏广告删掉”,实际要处理的是启动链路、活动图预加载、倒计时和配置开关四件事。

改之前,开发者的做法是搜索 SplashAdActivity,把 startActivity 注释掉,重新打包安装。第一次改完启动白屏,因为启动页 Activity 里的初始化也被一起删了;第二次补回初始化,冷启动正常,但按 Home 再切回来活动图又出现,因为 onResume 里还有一次展示调用;第三次把 onResume 整段删掉,结果隐私弹窗也不弹了。来回折腾了三轮,每轮都要反编译、改 smali、回编、签名、装机,时间主要花在定位和回归上。

用四要素重写之后,需求变成下面这样,一次性交代清楚目标、范围、边界和验收。附件里再补上截图、logcat、清单片段和配置片段,让 AI 不用猜页面在哪。

实例一需求原文(可直接套用)

目标:冷启动、从后台返回、从推送或深链进入时,都不再展示 SplashAdActivity 的自家活动开屏页;保留本地品牌启动图,初始化完成后直接进入首页,不等待活动图网络请求。

范围:应用包名 com.example.ownapp,版本 1.8.0;只处理 LauncherActivity 到 SplashAdActivity 的启动链路、SplashAdActivity 内的活动图容器与三秒倒计时、活动图预加载调用,以及配置键 splash_promo_enabled;不改首页、不改包名、不改版本号、不改应用名称。

边界:保留隐私政策与权限申请;保留登录态恢复、配置初始化、崩溃上报与推送令牌注册;不删除 SplashAdActivity 类本身,先移除启动链路中的跳转并保留空壳;不删除 drawable 与布局文件,确认无引用后再清理;不新增 SDK,不改网络地址,不更换签名。

验收:强制停止后冷启动五次,均不出现活动图且首页可点击;按 Home 后切回三次,不出现活动图;飞行模式下冷启动不白屏、不等待超过原包基线;首次安装同意隐私政策后可正常进入;从自家深链进入直接到目标页;apksigner verify 通过;logcat 无 FATAL EXCEPTION 与 ActivityNotFound。

附件这样准备:第一张是活动开屏页截图,用途写“标出要移除的自家活动开屏页及其跳过按钮位置”;第二段是 logcat 摘录,用途写“证明启动链路为 LauncherActivity 到 SplashAdActivity 再到 MainActivity”;第三份是清单片段,用途写“说明两个 Activity 的声明与启动模式”;第四份是配置片段,用途写“说明活动开关的键名与默认值”。每个文件的用途都超过十个字,附件系统会校验文件存在、不是目录、不是零字节且可读,然后按序号、路径、说明拼进需求一起发出。

附件 用途说明(不少于十字) 注意
splash-before.png 标出要移除的自家活动开屏页与跳过按钮位置 只截自家页面,不包含用户信息
startup-log.txt 证明启动链路依次经过三个页面的日志摘录 只保留相关行,去掉账号与设备标识
manifest-snippet.xml 说明两个 Activity 的声明方式与启动模式 只贴相关组件,不贴全部清单
config-snippet.json 说明活动开关的键名、默认值和生效范围 删掉接口地址、令牌和内部域名

修改完成后,先看项目目录里的 apktool 工程,确认改动集中在启动链路和开屏页,没有波及首页、隐私页和登录页。重点检查三处:LauncherActivity 的初始化是否还在,SplashAdActivity 的跳转是否已经断开,onResume 里是否还有第二次展示调用。三处都对,再进入回编和安装。第一次安装建议先不覆盖线上包,用测试机装,避免签名不同导致数据被清空。

验收时按需求里的用例逐条走:强制停止五次、Home 切回三次、飞行模式一次、深链一次、清除数据后首次安装一次。每次都用同样的观察点:首页是否直接出现、有没有白屏、隐私弹窗是否正常、logcat 有没有异常。最后再用 apksigner verify 确认签名,用 aapt 确认包名和版本号没有被改动。整个过程的日志会落在 pack.log 里,出问题时从日志末尾往前找第一条错误,效率最高。

区分启动页与自家活动开屏页的启动链路

先确认开屏页是独立 Activity 还是启动页内切换,再决定删跳转还是删容器

六、弹窗的触发条件:运营弹窗能关,合规提示必须留

弹窗比开屏页更复杂,因为它不是一条固定的启动链路,而是由很多条件触发的。同一个弹窗,可能只在首次安装出现,也可能每天出现一次;可能由远程配置控制,也可能由本地计时器触发;可能在首页 onResume 时弹,也可能在网络请求回调后弹。你不把触发条件找全,就会出现“我明明删了,怎么又弹了”的情况。

先把弹窗按性质分成四类,再决定动不动。合规类必须保留:隐私政策与用户协议、权限申请说明、未成年人提示、账号注销告知、敏感权限二次确认。安全类也必须保留:低于最低支持版本的强制更新、环境风险提示、账号异常提醒。运营类才是本文的处理对象:自家活动弹窗、优惠券、评分引导、推送引导、非强制更新提示。功能类要谨慎:新手引导、权限用途解释、核心功能引导,删之前先问产品经理。

弹窗类型 典型内容 处理原则
合规类 隐私政策、用户协议、权限说明、未成年人提示、注销告知 必须保留,不能以“去弹窗”为由删除
安全类 低于最低版本的强制更新、环境风险、账号异常 必须保留,可调整文案与跳转,不可绕过
运营类 自家活动、优惠券、评分引导、推送引导、非强制更新 可以关闭、降频或改成非阻塞提示
功能类 新手引导、权限用途解释、核心功能引导 先确认产品需求,能保留就保留

触发条件要按“生命周期、时间、配置、事件”四个维度去找。生命周期包括冷启动、热启动、onResume、首次进入首页、从登录页返回;时间包括首次安装、每日首次、每 N 次启动、固定延迟;配置包括远程开关、版本区间、人群标签、渠道;事件包括网络请求成功、推送到达、深链进入、点击某个入口、支付完成。把观察到的现象对应到这四个维度,基本就能找到触发点。

触发维度 常见条件 怎么验证
生命周期 冷启动、热启动、onResume、登录后返回 强制停止、Home 切回、登录退出再登录
时间 首次安装、每日首次、每 N 次启动、延迟 N 秒 清除数据、改系统日期、反复启动计数
配置 远程开关、版本区间、人群、渠道 用内部调试面板切换配置,或改测试环境返回值
事件 网络回调、推送、深链、点击入口、支付完成 逐条触发事件,观察弹窗是否出现

“删弹窗”其实有三个层次:触发调用、弹窗内容、调度与配置。只删弹窗类,调用还在,可能每次启动都请求一次配置,留下无用网络请求;只删调用,弹窗资源还在,代码里仍有死引用;只改配置,遇到默认值或本地缓存又会弹回来。需求里要写清楚处理到哪一层。比较稳妥的顺序是:先关配置或开关,再断开触发调用,最后在确认无引用后清理资源与类。这样每一步都能单独验证,也方便回退。

如果保留更新提示,还要把频率和“跳过此版本”写清楚。频率是每天一次、每周一次还是每个版本一次;跳过后是永久跳过还是只跳过当前版本;用户升级应用后是否重置;本地存储的键名是什么;清除数据后是否重新出现。这些细节不写,测试时就会出现“同一天弹了两次”“点了跳过明天又弹”的争议。把它们写成验收用例,比事后争论有效得多。

实例二:自家内部工具的自家更新提示弹窗

某团队的内部办公工具通过内网分发,每次启动都会请求版本接口,发现新版本就弹一个阻塞式对话框,只有“立即更新”和“稍后”两个按钮。运营团队又在同一个工具里加了一个活动推广弹窗,每个会话弹一次。现在的问题是:更新弹窗太频繁,出差在外网络不好时也会卡在对话框;活动弹窗和更新弹窗偶尔叠加,遮住登录按钮。团队希望保留安全底线,但把打扰降下来。

这个需求不能简单写成“把弹窗都删了”。低于最低支持版本时仍然必须强制更新,否则旧版本可能连不上新接口;隐私政策和权限说明也必须保留。真正要改的是三件事:非强制更新改成每天最多一次、可跳过当前版本;活动推广弹窗关闭;两个弹窗的展示顺序加互斥,避免叠加。注意,第三件事是防御性要求,不一定需要改代码,但验收时要覆盖。

实例二需求原文(可直接套用)

目标:非强制更新提示每天最多出现一次,用户可以跳过当前版本;低于最低支持版本时仍然强制更新;关闭自家活动推广弹窗;两个弹窗不再叠加遮挡登录入口。

范围:应用包名 com.example.internaltool,版本 3.2.0;只处理 MainActivity.onResume 中的 UpdateManager.check 调用、UpdateDialog 的展示频率与跳过逻辑、PromoPopupManager 的活动弹窗触发、配置键 promo_enabled 与 update_prompt_policy;不改登录页、不改首页功能、不改版本号。

边界:保留隐私政策与权限申请;保留最低支持版本判断与强制更新;保留登录态、崩溃上报、内网接口地址;不删除 UpdateManager 类,不绕过版本校验,不新增 SDK,不改签名。

验收:同一天连续冷启动三次,非强制更新提示只出现一次;点击“跳过此版本”后再次启动不出现,升级到新版本后重新判断;把测试配置的最低支持版本调高后,旧版本仍然强制更新且不能进入首页;活动推广弹窗在冷启动、热启动、深链进入时都不出现;首次安装隐私弹窗正常;logcat 无崩溃;apksigner verify 通过。

附件准备四样:更新弹窗与活动弹窗叠加的截图,用途写“说明两个弹窗同时出现并遮挡登录按钮”;MainActivity 的 onResume 日志,用途写“证明更新检查与活动弹窗都在 onResume 触发”;版本接口的测试返回样例,用途写“说明最低支持版本与最新版本的字段”;本地存储键的说明,用途写“说明上次提示日期与跳过版本的保存位置”。接口样例里的内网地址、令牌、真实用户信息要全部替换成占位值。

修改完成后,重点检查四个地方:非强制更新的频率判断是否落在本地存储里,跳过的版本是否按版本号比较,最低支持版本的强制分支是否还在,活动弹窗的触发是否从 onResume 和配置两处都断开。只断一处,另一处仍可能把弹窗带回来。两个弹窗的互斥逻辑如果原本没有,也可以在需求里加一句“更新弹窗展示期间不展示活动弹窗”,让它成为验收的一部分。

测试时用内部调试面板切换版本配置,不要直接改线上接口。把最低支持版本临时调高,确认旧包仍然被强制更新;把最新版本调低,确认不再提示;把系统日期往后改一天,确认每日频率生效;点“跳过此版本”后冷启动三次,确认不再出现;再清除数据,确认首次安装的隐私弹窗和更新提示顺序正常。每一步都记录截图和 logcat,最后一起归档。

梳理自家更新提示与活动弹窗的触发条件

运营弹窗可以关,合规与安全提示必须留,触发条件要逐条验证

七、第四步:话术与附件,把需求钉在证据上

四要素写好后,还要解决两个表达问题:怎么让需求读起来像正常说话,怎么让 AI 看到你看到的现场。电脑版详情页内置了 3000 条话术,按六类场景各 500 条整理,点选后就能填入输入框。话术适合解决“不知道从哪写起”的问题,但不适合原样发送,因为里面的包名、页面名、版本号都是示例,必须替换成自己的项目信息。

推荐三种句式。第一种是“现象加定位加目标”,先说看到了什么,再说页面在哪,最后说希望变成什么样。第二种是“保留清单”,把不能动的东西一次列全。第三种是“验收动作”,用自己准备执行的测试步骤收尾。三种句式拼起来,就是一段既有现场感、又有边界感的需求。

  1. 现象句式:冷启动后先出现三秒自家活动图,右上角有跳过,随后进入首页;按 Home 再切回来活动图会再出现一次。
  2. 定位句式:启动链路为 LauncherActivity 到 SplashAdActivity,再到 MainActivity,前台组件名来自 logcat,截图和日志见附件。
  3. 保留句式:隐私政策、权限申请、登录态恢复、配置初始化、崩溃上报都不能动,开屏页类先保留为空壳。
  4. 验收句式:强制停止后冷启动五次、Home 切回三次、飞行模式一次,均不出现活动图,首页可点击,logcat 无异常。

点选话术之后,至少替换五类占位符:包名与版本、Activity 或页面名称、配置键与默认值、必须保留的功能、验收动作。只改一两个词就发出去,AI 很容易把示例里的页面当成你的页面。更稳妥的做法是先在本地把话术改成一段完整的需求,再通读一遍,确认里面没有“示例”“某某”“待定”这类词。

附件系统是电脑版的另一个辅助。一次可以选择多个文件,每个文件都要写用途说明,说明不能少于十个字;系统会校验文件是否存在、是不是目录、是不是零字节、是否可读,然后把序号、路径、说明拼成一份清单,随需求一起发出。这个设计的好处是 AI 能直接看到证据,而不是只靠文字想象;坏处是附件太多会稀释重点,所以每个附件都要有明确用途,不要一股脑把整个项目目录塞进去。

附件类型 用途说明怎么写 不要放什么
页面截图 标出要处理的页面、按钮位置和需要保留的区域 用户头像、手机号、订单号等个人信息
日志摘录 说明启动顺序、弹窗触发点或崩溃堆栈的关键几行 整份日志、设备标识、账号令牌
清单片段 说明相关 Activity 的声明、启动模式与入口关系 与本次需求无关的组件和权限
配置片段 说明开关键名、默认值、生效版本与回退逻辑 接口地址、密钥、内网域名
操作录屏 说明从点击图标到弹窗出现的完整操作路径 包含聊天记录、通讯录等隐私内容

history 只留原话

电脑版的 history.ini 只保存你在输入框里写的原始文字和日期,不保存附件说明,也不保存 AI 改写后的版本。也就是说,历史记录是你自己的审计线索,但附件里的证据不会跟着进历史。需求正文必须自包含,不能只写“具体见附件”。

这条规则很实用。过了一周,你回看历史,如果只看到“把开屏广告关掉,附件有截图”,你很难想起当时到底改了哪个页面、保留了哪些提示。正确写法是把四要素写全,附件只做补充。附件说明写清楚“这张图证明什么”,而不是“这是截图”。文件名也建议带序号和用途,例如 01-splash-before.png、02-startup-log.txt,比“新建文件夹”里的随机名字好找得多。

历史记录在详情页里最新在上,保留完整原文,右侧有“选择”可以把某条历史回填到输入框。这个功能适合迭代:第一次需求写宽了,回填后收紧范围;第二次改偏了,回填后补一条保留项。每次回填后先改第一行,写上版本号和本次目标,例如“1.8.0 去活动开屏,保留品牌启动页”,以后搜索和对照都方便。不要把历史当成草稿箱,发出去之前还是要通读。

附件校验失败时,先看四个原因:路径不存在、选到了目录、文件是零字节、文件不可读。把文件复制到项目目录附近,确认能被普通程序打开,再重新选择。还有一个小细节:附件说明少于十个字会被拒绝,这不是故意刁难,而是强迫你写清楚用途。写“截图”不行,写“标出活动开屏页的跳过按钮位置”就合格。

八、第五步:AI 修改与四步打包

点“立刻修改”之后,工具会把输入框里的原文和日期写进 history.ini,然后把需求送进右侧 AI 工作区执行。AI 完成时会在项目目录留一个 ai_done.flag,主窗口每 2 秒轮询一次,读到就删除,等待上限是 1 小时。这个机制意味着两件事:第一,不要因为暂时没看到结果就反复点,重复提交只会让历史记录变乱;第二,等待期间可以准备测试设备、整理验收用例,但不要关闭项目,也不要把项目目录移走。

完成后先审改动,不要急着打包。打开项目目录里的 apktool 工程,看看哪些文件发生了变化:清单里有没有多删组件,启动链路的 smali 是不是只断了目标跳转,布局和资源有没有被整段清空,配置读取有没有留下空指针。重点确认三件事:初始化还在、隐私入口还在、首页启动路径没有断。只要有一项不对,就回退重来,不要带着疑问往下走。

如果 AI 改偏了,最有效的动作不是继续加话,而是回填历史、缩小范围、补一张证据图,再跑一轮。比如它把启动页也删了,就在范围里明确写“只允许改 SplashAdActivity 及其调用点,LauncherActivity 只能删除跳转,不得删除初始化”;它把隐私弹窗一起关了,就在边界里把隐私页的类名和调用点写出来。一次只纠正一个偏差,下一轮的改动才容易看懂。

确认改动范围合理后,进入打包。电脑版把打包拆成四步,顺序不能乱,中间任何一步失败都不要跳过。下面这张表把每一步的目的和常见问题列在一起,照着核对即可。

步骤 命令 目的 常见问题
回编 apktool b -f -o build\unsigned.apk 把 apktool 工程重新编译成未签名 APK 资源引用找不到、9-patch 格式错误、smali 寄存器不匹配
对齐 zipalign -f -p 4 输入.apk 输出.apk 让未压缩数据按 4 字节边界对齐,减少运行开销 顺序放错,先签名后对齐,签名被破坏
签名 apksigner sign --ks ... --out ... 给对齐后的包签名,生成可安装产物 密钥格式不对、别名写错、口令读取失败
校验 apksigner verify --print-certs 输出.apk 确认签名真的写进去了,并打印证书信息 跳过这一步,装到设备才发现没签上

回编时,-f 表示覆盖旧产物,避免拿到上一次的残留文件。报错最常见的是资源引用和 9-patch:布局里删了控件却留下引用,或者点九图被改坏,都会在回编阶段暴露。遇到这类错误,先看 apktool.log 的最后一段,找到具体文件和行号,再决定是补引用还是恢复资源。不要为了“先编过去”而随手删掉整个布局,那样很可能把首页也弄坏。

对齐必须在签名之前。zipalign 的 -p 参数会把 .so 文件按页对齐,4 表示 4 字节边界。很多人习惯先签名再对齐,结果签名校验直接失败,因为对齐过程改动了文件内容。正确顺序是:未签名包先对齐,再签名,最后校验。三步之间不要手工改文件,也不要用压缩工具重新打包。

签名有四种方式可选:默认签名、JKS 或 keystore、PEM 加 PK8、随机签名。内部测试图省事可以用默认或随机签名,但要记住随机签名的包不能覆盖安装到已有应用上,必须先卸载,数据会丢;要发版、要保留老用户升级路径,就必须用团队自己的发布密钥。口令通过环境变量读取,不拼进命令行,也不会写进日志,这一点在共用电脑上尤其重要。

签名方式 适合场景 注意事项
默认签名 临时测试、内部验证 不要用于对外分发,换签名后无法覆盖升级
JKS 或 keystore 团队正式发布、需要持续升级 备份密钥与口令,记录别名和有效期
PEM 加 PK8 已有证书链、需要指定私钥格式 确认私钥与证书匹配,格式错误在 verify 阶段会暴露
随机签名 一次性演示、不覆盖安装的验证 必须先卸载旧包,应用数据会清空

签名版本默认是 v1、v2、v3 一起开。v1 照顾老系统,v2 和 v3 提供更完整的完整性校验;v4 是可选方案,按设备与分发要求决定。不要为了“包小一点”随手关掉 v2 或 v3,也不要只签 v1 就发给新设备。改签名配置属于高风险动作,需求里没有写就不要顺手改。

pack.log 记录打包全过程,出问题时先看它。最有效的读法是从末尾往前找第一条错误,而不是从头逐行读。回编失败通常能直接看到资源路径和行号;签名失败会提示密钥格式、别名或口令;对齐失败会提示输入输出路径或文件被占用。修完一个错误再跑一次,不要一次改五处,否则下一个错误来自哪次修改都说不清。

打包完成后,工具会自动走安装预览:先用 adb 找设备,把包装上,再用 am start -W -n 包名/Activity 拉起。组件名有三档查找:先读 config.ini 里的 LaunchableActivity,读不到就用 cmd package resolve-activity --brief 查询,最后再走旧方式兜底。拉起后用 dumpsys 复核前台应用,手机通过 scrcpy 投屏,模拟器会被提到最前。这个流程能帮你快速看到改完的效果,但真正的验收还是要按下一节的用例逐条走。

如果安装失败,先分三类:签名不一致、版本降级、ABI 不匹配。签名不一致就卸载旧包或换回原签名;版本降级就把 versionCode 调高;ABI 不匹配就换对应架构的设备或补充库文件。错误提示里通常已经写明原因,不要靠猜。尤其是签名问题,apksigner verify 的结果比安装器的提示更准确。

回编对齐签名校验四步打包流程

回编、对齐、签名、校验四步按顺序执行,任何一步失败都不要往下跳

九、第六步:冷启动与弹窗触发测试

验收不是打开看一眼。开屏页和弹窗都属于“条件触发”的功能,只测一次冷启动,很可能漏掉热启动、首次安装、断网、深链这些路径。建议把下面这张矩阵打印出来,每测完一行就打勾,记录设备、版本、时间和结果。测试机最好准备两台:一台常用系统版本,一台较新的系统版本,覆盖权限和启动行为差异。

测试场景 操作 预期结果
冷启动 强制停止后点图标,连续五次 不出现活动开屏页,直接进入首页可交互
热启动 Home 键、最近任务、返回键各两次 不重新展示开屏页,页面状态保持
首次安装 清除应用数据后重新启动 隐私政策正常,同意后直接进入首页
飞行模式 断网后冷启动一次 不白屏、不长时间等待,直接进首页或给出可操作提示
弱网 限速或高延迟网络下冷启动 不因为活动图请求阻塞首页
深链进入 用 adb 发送 VIEW 意图打开自家链接 直接到目标页,不插播开屏页
推送进入 从通知栏点击自家推送 直接到目标页,弹窗不遮挡内容
每日频率 同一天多次启动,再把日期往后调一天 同一天只出现一次,跨天后按规则重新判断
跳过版本 点击跳过当前版本后反复启动 不再提示该版本,升级后重新判断
强制更新 把测试配置的最低支持版本调高 旧版本仍被强制更新,不能绕过进入首页
权限拒绝 首次启动拒绝非必要权限 应用不崩溃,权限说明仍可再次触发
adb shell am force-stop com.example.ownapp
adb shell am start -W -n com.example.ownapp/.ui.LauncherActivity
adb shell am start -W -a android.intent.action.VIEW -d "ownapp://activity/detail?id=1" com.example.ownapp
adb shell pm clear com.example.ownapp
adb logcat -c
adb logcat -d | findstr /i "FATAL ActivityNotFound ANR NetworkOnMainThread"
adb shell dumpsys activity activities | findstr mResumedActivity

am start -W 会输出 TotalTime 和 WaitTime,可以和原包基线对比。不要死抠几十毫秒的差异,手机状态、后台进程、网络都会影响结果;重点看有没有因为等待活动图请求而多出明显的一截。更好的观察方式是录屏:从点击图标开始录,逐帧看首页出现的时间,以及中间有没有白屏或闪跳。两次录制用同一台设备、同一个网络,结论才可信。

logcat 要重点搜四类信息:FATAL EXCEPTION 表示崩溃,ActivityNotFound 表示入口被删坏,ANR 表示主线程被阻塞,NetworkOnMainThread 表示网络请求放错线程。改开屏页时,最常见的崩溃是跳转目标不存在,最常见的卡顿是把网络请求留在了启动主线程。清空日志后再启动,能减少历史噪声;如果日志太多,用包名或 Activity 名过滤。

弹窗触发测试要单独做一轮。先改系统日期验证每日频率,再用内部调试面板切换配置验证开关,再改测试接口的版本字段验证强制更新,最后清数据验证首次安装。每改一个条件,都要把应用强制停止再启动,避免进程内缓存掩盖问题。点“跳过此版本”后,至少冷启动三次,再杀进程重启一次,确认本地存储真的生效;清除数据后,确认提示按首次安装逻辑重新出现。

装机预览可以作为第一轮快速检查:看图标、应用名、启动页、首页、弹窗顺序,确认没有明显异常。手机通过 scrcpy 投屏,操作和截图都方便;模拟器会被带到最前,适合快速回归。但最终验收要在真机上做,尤其是权限、通知、深链和厂商系统差异,模拟器覆盖不到。预览通过不等于验收通过,这一点要跟团队说清楚。

现象 可能原因 处理方式
启动白屏 启动页主题或初始化被误删 恢复启动页与初始化,只断开活动页跳转
点击图标闪退 入口 Activity 被删或清单声明缺失 恢复清单与入口类,检查 ActivityNotFound
仍然出现活动图 还有第二处调用、热启动入口或缓存配置 全局搜索调用点,检查 onResume 与配置默认值
弹窗重复出现 频率键未写入、被清除或判断条件写错 检查本地存储键、日期格式与跨天逻辑
覆盖安装失败 签名不一致或 versionCode 降低 换回原签名,或提高 versionCode 后重打包
安装后无入口 启动 Activity 被误删或 exported 配置错误 对照原包清单恢复入口声明,重新校验

最后把证据归档:改前截图、改后截图、冷启动录屏、logcat 摘录、pack.log、apksigner verify 输出、测试设备与系统版本、测试人和日期。归档不是形式主义,下一次改版本、换运营策略、排查线上反馈时,这些材料能帮你快速还原现场。验收结论只写“通过”两个字没有意义,写清楚“在什么设备、什么网络、执行了哪些用例、结果如何”,才算可追溯。

十、验收清单、两个实例复盘与下载

两个实例看起来一个在改开屏页、一个在改弹窗,底层方法是一样的:先用证据确认归属和触发点,再用四要素写清目标、范围、边界、验收,然后让 AI 做小范围修改,最后按矩阵逐条测试。真正决定成败的不是某一句提示词,而是你有没有把“删什么、留什么、怎么验收”提前写死。

实例 核心改动 验收关键 保留项
自家电商 App 活动开屏页 断开启动跳转、移除倒计时与预加载、关闭活动开关 冷启动五次、热启动三次、断网、深链、首次安装 品牌启动页、隐私、初始化、登录态
自家内部工具更新与活动弹窗 更新提示降频并可跳过、关闭活动弹窗、加互斥 同一天一次、跨天恢复、强制更新、跳过持久化 隐私、权限、最低版本校验、内网接口

下面这份清单可以直接复制到测试文档里,每完成一项就打勾。清单覆盖了修改前、修改中、修改后三个阶段,建议至少两人交叉检查:一人按需求执行,一人按清单复核,避免“自己测自己”的盲区。

打勾方式:□ 未完成,☑ 已完成。每完成一项,就把对应的方框改成勾选状态,并在备注里写明设备、系统版本和测试时间,方便后续复核。

序号 检查项 通过标准
1 归属确认 包名、签名、版本均与自家构建一致,有书面授权
2 原包备份 原始 APK、SHA-256、签名摘要、keystore 均已归档
3 触发点记录 冷启动、热启动、首次安装、深链路径均有截图或日志
4 需求四要素 目标可观察、范围可定位、边界有清单、验收可执行
5 附件说明 每个附件用途不少于十字,已脱敏,校验通过
6 改动范围 只涉及目标页面、调用点、资源和配置,首页未受影响
7 合规提示 隐私政策、权限说明、未成年人提示仍正常出现
8 安全校验 最低版本强制更新、登录态、接口校验均保留
9 冷启动 连续五次不出现目标开屏页,首页可交互
10 热启动 Home、最近任务、返回键各两次均不复现
11 首次安装 清除数据后隐私流程完整,之后直达首页
12 断网与弱网 不白屏、不长等待,错误提示可操作
13 深链与推送 直接到目标页,不插播开屏,弹窗不遮挡
14 弹窗频率 同一天只出现一次,跨天按规则恢复
15 跳过与强制 跳过持久化;低于最低版本仍强制更新
16 日志 无 FATAL、ActivityNotFound、ANR、主线程网络异常
17 签名校验 apksigner verify 通过,证书与发布密钥一致
18 证据归档 截图、录屏、日志、pack.log、测试记录齐全可追溯

验收签收模板

版本:____ 设备与系统:____ 网络环境:____ 测试日期:____

执行用例:冷启动五次、热启动三次、首次安装、飞行模式、弱网、深链、每日频率、跳过版本、强制更新。

结果:____ 异常说明:____ 回退包位置:____

测试人:____ 复核人:____ 结论:通过 / 不通过

用户评价

“以前改自家活动开屏,靠搜 smali、注释跳转、反复回编,最怕删多了白屏。现在先写清启动链路和保留项,再让电脑版执行,冷启动和断网各测一遍,心里有底。”
—— 周明远(连锁零售企业安卓开发负责人)

“我第一次把启动页和开屏页搞混,差点把入口删掉。后来按教程把前台 Activity、截图和日志一起附上,需求一次就说清了,隐私弹窗也保住了。”
—— 李珂(独立开发者)

“内部工具的更新弹窗改成每天一次、可跳过,但最低版本仍然强制更新。验收时用日期和测试配置逐条切,比只点一次启动可靠得多,pack.log 也帮我定位过一次密钥格式问题。”
—— 陈晓帆(SaaS 公司客户端工程师)

“我们信息中心的内部工具版本多、设备杂,最有用的是那份验收清单。冷启动、热启动、深链、清除数据都走一遍,出了问题还能从 history 回填原话,不用重新组织语言。”
—— 王振宇(高校信息中心移动端维护)

“产品和开发以前为‘弹窗到底关没关’争半天,现在需求里直接写目标、范围、边界、验收,运营位能关、合规提示不能动,大家按同一张清单签字,沟通成本低了很多。”
—— 赵倩(创业公司产品经理)

合规提醒

动手之前请再确认一次

本文只适用于你拥有自有版权,或已获得明确授权的应用。请勿用于破解、去除他人应用的授权验证、绕过付费内容或安全机制,也不要将方法套用到他人商业应用上。

发布前请确认隐私政策、权限说明、开源许可证与分发渠道要求;涉及第三方 SDK、广告合同或用户数据的功能,先取得业务和法务的书面确认。改动自家应用也要保留必要的合规提示与安全校验,不能以“去弹窗”为由一并删除。

回到工具本身,安卓修改大师智改工坊的定位很明确:把自然语言需求变成可执行的改包流程,把反编译、修改、回编、对齐、签名、校验这些步骤串起来,让你把精力放在“改什么、留什么、怎么验”上。需求写得越清楚,结果越稳定;验收做得越细,回退越从容。

如果你在电脑上完成本文的流程,可以使用安卓修改大师电脑版;如果你希望直接在手机或平板上处理自家应用,也可以了解安卓修改大师安卓版。两个版本的入口都在官网 https://www.apkeditor.cn/ai-version.aspx,具体能力和系统要求以页面说明为准。

只需说话,就能让应用变成你想要的样子

安卓修改大师智改工坊

把需求说清楚,再让工具去执行

安卓修改大师电脑版:面向 Windows 10/11 64 位,导入 APK 后用自然语言描述改动,自动完成反编译、修改、回编、对齐、签名与校验,并可安装到手机或模拟器预览。

安卓修改大师安卓版:面向 Android 10 及以上的 ARM64 手机和平板,在设备本地完成反编译、修改、回编、对齐与签名,支持导入 APK、JAR、APKS、XAPK、APKM,成品可直接安装或分享。

官网:www.apkeditor.cn 介绍与下载:https://www.apkeditor.cn/ai-version.aspx

立即下载

只需说话,就能让应用变成你想要的样子