2. 输出控制策略的核心概念
策略这东西,说白了就是一组规则。你告诉SDK:“什么时候可以输出,输出什么,输出给谁。”我见过不少开发者,上来就写代码,策略完全靠脑子记。结果呢?项目一迭代,谁改过策略都搞不清了。
咱们先把这个基础打牢。策略本身并不复杂,但它的结构设计,决定了你后面能不能灵活调整。嗯,咱们一点点拆开看。
2.1 策略的基本构成
任何一个输出控制策略,都跑不出三个核心要素:条件、动作、作用域。你可以把它理解成“如果…就…对谁生效”。
策略三要素对应关系
| 要素 | 含义 | 举个例子 |
|---|---|---|
| 条件(Condition) | 触发策略的约束或事件 | “用户设备系统版本 < Android 12” |
| 动作(Action) | 满足条件后执行的操作 | “屏蔽设备标识符输出” |
| 作用域(Scope) | 策略影响的数据范围或模块 | “仅对广告SDK模块生效” |
我举个例子你感受下。咱们要控制“低版本系统不输出设备ID”。条件就是“系统版本低于Android 12”。动作是“输出结果中移除oaid字段”。作用域则是“仅限标识符模块”。你想想看,这三样缺一个,策略就执行不了,或者执行错了地方。
我的一个习惯:设计策略时,先把条件写在最前面。因为条件决定了策略是否会被执行,这个判断成本最低。动作和作用域可以后面再细化。
2.2 策略的类型
策略分两大类:静态策略和动态策略。这两者的区别,说白了就是一个是“死”的,一个是“活”的。
- 静态策略:编译时就定死了。改策略得重新发版。优点是简单、性能好、零运行时开销。缺点是灵活性差。我之前有个项目,隐私合规要求改了,只能等下一个版本发布,那叫一个难受。
- 动态策略:运行时从远端拉取或本地动态加载。改策略不用发版,实时生效。缺点是需要网络、有延迟、还要处理策略版本冲突。
怎么选?我个人的建议是:核心隐私底线用静态策略,比如“禁止输出用户明文手机号”,这种不能绕过。而像“某个广告位的设备标识符输出策略”,这种经常变的需求,用动态策略更合适。
注意:千万不要让动态策略覆盖掉静态策略中的底线规则。我曾经见过一个事故:服务器下发了一个空策略,结果静态策略被覆盖,敏感数据直接输出到了日志里。这属于策略优先级设计的问题,后面会详细讲优先级。
2.3 策略的生命周期
策略不是写完了就完事的。它有自己的生命周期,从出生到销毁,每一个阶段都有讲究。
我一般把策略生命周期分成五个阶段:
- 定义:写规则。可以是代码里的配置,也可以是配置文件里的JSON。
- 加载:把策略读进内存。静态策略在应用启动时加载,动态策略在启动后异步拉取。
- 匹配:每次输出时,检查当前环境是否满足策略条件。这一步是性能瓶颈,要优化匹配顺序。
- 执行:命中策略后,执行对应的动作。比如拦截输出、修改输出内容、或者触发一个回调通知业务方。
- 销毁:策略失效或更新时,释放旧策略的内存和资源。
为什么要关注生命周期?因为很多坑都出在“加载”和“销毁”这两个阶段。比如动态策略还没加载完,SDK就已经执行了一次输出,这时候应该怎么办?用默认策略还是直接拒绝输出?这都是实战里躲不开的问题。
避坑记录:我建议在加载阶段使用“策略就绪标志位”。在标志位置为true之前,所有输出一律走最严格的默认策略。这个做法虽然保守,但能保证不出安全事故。
好了,讲完这些基础概念,咱们用一张图来串联下整个知识体系。这样你脑子里会有一个整体的框架,后面学起来不会觉得散。
这张图把咱们刚才讲的内容串起来了。你可以看到,策略的核心是三要素,然后根据部署方式分成静态和动态,再根据时间线有了生命周期。后面每一章都会围绕着这个图展开。你记着这张图,后面学起来会轻松很多。