一个基础问题:关于SDK初始化时机的选择

天下唯庸人无毁无誉。------ 梁启超

最近在开发新功能引入一个SDK时,遇到了这个问题。算得上是比较典型的客户端开发场景,因此在本文中整理记录。

问题描述

背景阐述

  1. 产品新需求里需要用到端侧 AI 能力,已有 AI-SDK.aar 提供相关能力;
  2. 在使用 AI-SDK 之前,需要对它进行初始化,初始化耗时约 1s,且在进程存活期间 只需要执行一次初始化 即可;
  3. 只有完成初始化后,才能调用 AI-SDK 接口,供业务方使用;
  4. AI-SDK 会在内存中加载模型,产生 8M 的内存占用。

以上就是需求和技术的背景,最初我是把该 SDK 放在进程启动时,异步初始化的,功能使用起来没有任何问题。但是,公司内部会有 自动化测试 ,校验不同 APP 版本之间性能差异。由于新版本在进程启动时初始化 AI-SDK,产生了 8M 的应用内存劣化,这在性能方面是不能接受的。

方案选择

这个问题本质上是如何平衡 新功能引入APP 性能指标 之间关系的问题。有三种方案,列举如下:

方案一:保持原设计,在进程初始化阶段进行 AI-SDK 初始化

这种方案是最容易想到的实现方式,也是大多数 SDK 文档中提供的接入方法。

  • 优点: 使用简单,功能稳定,当业务页面调用 AI 能力接口时,一定是已经完成了 SDK 初始化。
  • 缺点: 对于不需要该功能的用户,仍然加载了 AI-SDK,导致内存额外消耗。

方案二:在用户接触到 AI 能力之前,进行初始化

需要识别业务上使用AI能力的入口处,在入口处完成初始化。

  • 优点: 按需加载,降低内存占用。
  • 缺点: 业务上需要有明确且统一的入口。

这种方式其实是最佳的方案,兼顾用户体验与性能,但存在一个明确的限制,就是所有对 AI-SDK 能力调用,都应该在某个时机之后。开发者的目标就是找出 这个唯一的时机,并且越晚越好。方案一本质是方案二的特化,将时机提前到了进程创建时。

方案三:直到用户使用到 AI 能力之时,才进行初始化

是最晚的加载时机,也是最不易控制的时机。因为初始化是一个耗时操作,意味着所有AI能力的接口,都要做成 suspend 的阻塞式,导致无法在 UI 线程中直接调用。如果代码结构设计不佳的话,这将是一场灾难。

  • 优点: 极致的按需加载。
  • 缺点: 对能力调用方产生严格限制。

举例来说,应用需要在内存中维护一个 Boolean 变量,其含义为"本设备是否支持智能抠图能力",这个变量的取值依赖于 AI-SDK 初始化的结果。同时,业务上有多处需要取这个变量的值。依照方案三,就需要在首次判断该状态值时,对 AI-SDK 执行初始化。这会导致该判断函数是一个耗时的操作,这明显超出了函数设计的本意 ------ 一个判断状态的函数,承担了它不该承担的职责。

最终方案

在综合考虑 性能、应用场景、实现成本 后,选择使用方案二。

kotlin 复制代码
object AISdkManager {
    private var initialized = false

    fun initIfNeeded(context: Context) {
        if (!initialized) {
            AISdk.init(context) // 真正的初始化
            initialized = true
        }
    }

    fun doSomething(param: String) {
        initIfNeeded(App.context)  // 确保已初始化
        AISdk.doSomething(param)
    }
}

总结

是客户端开发中一个典型的模式,加工一下可以作为初级面试题。

相关推荐
2603_949462102 小时前
Flutter for OpenHarmony社团管理App实战:预算管理实现
android·javascript·flutter
王泰虎4 小时前
安卓开发日记,因为JCenter 关闭导致加载不了三方库应该怎么办
android
2601_949543018 小时前
Flutter for OpenHarmony垃圾分类指南App实战:主题配置实现
android·flutter
2601_949833399 小时前
flutter_for_openharmony口腔护理app实战+知识实现
android·javascript·flutter
晚霞的不甘9 小时前
Flutter for OpenHarmony从基础到专业:深度解析新版番茄钟的倒计时优化
android·flutter·ui·正则表达式·前端框架·鸿蒙
鸟儿不吃草9 小时前
android的Retrofit请求https://192.168.43.73:8080/报错:Handshake failed
android·retrofit
Minilinux20189 小时前
Android音频系列(09)-AudioPolicyManager代码解析
android·音视频·apm·audiopolicy·音频策略
李子红了时10 小时前
【无标题】
android
Android系统攻城狮11 小时前
Android tinyalsa深度解析之pcm_close调用流程与实战(一百零四)
android·pcm·tinyalsa·音频进阶·音频性能实战·android hal
weixin_4111918411 小时前
LifecycleEventObserver和DefaultLifecycleObserver使用
android