去年的时候,在 XSC 中要加入开屏广告,开始计划从 XIC 中把小伙伴的实现直接复用过来。结果一看,复杂度超出了预期,里面用到了他自己实现的线程池,又是提交任务,又是睡眠等待,又是跨线程指定 UI 主线程执行,几乎直接吓退,只好按照自己的思路重新实现了一版。因为要兼顾 app 的冷启动和热启动,所以需要关注本 app 内所有的 Activity 的活动情况,还要酌情排除其中的某些,所以比较核心的能力有两个类,一个是负责监控 Activity 的 SplashAdMonitor
,一个是负责广告的加载以及展示的 SplashAdController
。后者需要跟广告 SDK 打交道,也要和作为开屏广告展板的 SplashActivity
打交道。
最终的逻辑落实肯定是在 SplashActivity
里面。所以让小伙伴把上面的两个类用回到 XIC 中时,由于 SplashAdController
会导致其 SplashActivity
的实现大加变化,他唯恐忙中出错,于是只使用了 SplashAdMonitor
。其实即便就是 SplashAdMonitor
的功能,也可以用更简单的 process lifecycle 组件来实现,只不过当时老夫对这块还不了解,而且考虑到 XSC 技术栈的纯粹(仍然全是 Java),就没染手。
这一阵 XIC 的开屏广告根据线上的数据来看,发现似乎有较大的问题。在追查调试过程中,实在难以接受原来实现的那么多线团绕来绕去,于是痛下决心,把 SplashAdController
增强升级为了 SplashController
,它不仅被动接受加载和展示广告的指挥,还会主动反馈这个过程中的事件,供 SplashActivity
决定相应的响应行为,其实很简单,主要就是及时关闭。测试了两三天,效果似乎还可以,只是有个已知 bug,待节后补掉。此一事。
在此过程中,又发现之前的实现里对 Google UMP 的实现相当诡异,也进行了调整,但是效果仍需持续关注。调试 UMP 效果时,需要对本设备所处地理位置进行 mock,当前的实现里是,如果检测到构建为 debug 版本,就强行 mock 为 GDPR 区域,这个有点过于粗暴,而且可能会干扰到其它可能的测试。于是又牵扯出另一桩老夫一直心心念念的需求,就是应该实现一个可视界面,允许运行时按需将其呼出,对特定的设置项进行调整,类似于系统已经存在的 Preferences 相关的界面组件(Activity 或者 Fragment)。但是,用系统的这些个支撑就要跟 XML 搅和在一起,而预期是最好跟 JSON 或者 SharedPreferences 比较亲和。找来找去,还真让老夫找到一个比较冷门的项目,比较简单,但看上去够用。不过它停更于三年前,更新构建相关的脚本以及依赖就又折腾了一会儿,而且还要对 Kotlin 语言的演进也随之跟上。
最后剩下的有一两个 warning,都跟将 Any 类型强转为集合类有关。一开始野心勃勃,想将它们安全消除,于是查阅了一些资料,如 android – Kotlin. Unchecked cast: Any? to HashMap<String?, String?>? – Stack Overflow 和 Kotlin Cast Any to List or Map: Unchecked Cast (luasoftware.com),到最后还是放弃了执念,留着也没什么。而且从这个项目里,还学会了在构建脚本中分别使用
1 2 |
debugImplementation project(':library') releaseImplementation project(':library-no-op') |
这样的指示技巧。像这种东西,真是属于“心里期望有,但不亲眼见之前不知道已经有”的范畴的东西。