4. 初始化:SDK初始化参数详解、生命周期管理

初始化这步,看着就几行代码,实际上坑最多。我刚开始接手隐私共享SDK的时候,觉得把appId和secretKey填上就完事了——结果跑起来直接崩,日志里一堆“参数校验失败”。后来才明白,每个参数背后都有设计逻辑,漏一个就得花半天排查。

4.1 核心初始化参数

先看一组最常用的参数。下面这个表是我整理的,每次对接新项目我都拿它对照一遍。

参数名类型必填说明
appIdString是应用唯一标识,由平台分配
secretKeyString是签名密钥,长度至少32字节
serverUrlString是服务端地址,格式https:// + 域名 + 端口
timeoutint否请求超时毫秒数,默认10000
retryCountint否失败重试次数,默认3
logLevelint否日志级别:1-ERROR, 2-WARN, 3-INFO, 4-DEBUG
storagePathString否本地缓存路径,不传使用默认
enableEncryptboolean否是否启用端到端加密,默认false

appId和secretKey的校验经常出问题。我遇到过好几次,测试环境用的是平台给的示例密钥,长度刚好32位,但正式环境的密钥是48位的——SDK内部没做长度适配,直接报错。后来我学乖了,初始化之前先检查secretKey的字节长度,不够的主动补零或报错。

4.2 初始化代码示例

上代码。这算是最标准的初始化写法了。

// 创建配置对象
PrivacyConfig config = new PrivacyConfig.Builder()
    .appId("wx_app_2024_001")
    .secretKey("a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6")
    .serverUrl("https://privacy.example.com/api/")
    .timeout(15000)                // 15秒超时
    .retryCount(2)                 // 失败重试2次
    .logLevel(LogLevel.INFO)      // 仅输出INFO及以上日志
    .enableEncrypt(true)           // 开启加密传输
    .build();

// 执行初始化
PrivacySDK.init(context, config);
警告:init方法必须在Application.onCreate或主线程Service的onCreate中调用,且只调用一次。重复调用会触发IllegalStateException。

4.3 生命周期管理

生命周期说白了就是把SDK当成一个有状态的机器。你得知道它什么时候能用,什么时候该停。我画了个流程图,看完就清楚了。

SDK生命周期流程 未初始化 初始化中 就绪 工作中 已销毁 初始化失败 关键说明 • 状态转换由SDK内部自动管理 • 销毁后不可恢复,需重新init • 工作中调用stop()回到就绪

4.4 状态转换与回调

初始化过程中有几个关键状态回调,你可以在回调里做自己的处理。比如在onReady之后开始业务请求,在onError时弹个重试提示。

PrivacySDK.init(context, config, new InitCallback() {
    @Override
    public void onReady() {
        Log.d("SDK", "初始化完成,可以开始共享数据了");
        // 这里才适合调用 start() 启动业务
    }

    @Override
    public void onError(ErrorCode code, String msg) {
        Log.e("SDK", "初始化失败: " + code + " - " + msg);
        // 我习惯在这里做重试逻辑,但注意不要无限重试
    }

    @Override
    public void onDestroy() {
        Log.d("SDK", "SDK已销毁,资源释放完毕");
    }
});
技巧:我通常在onError回调里判断错误码,如果是网络不可达(ErrorCode.NETWORK_ERROR),等待3秒后重试一次;如果是密钥错误(ErrorCode.AUTH_FAILED),直接弹窗提示用户检查配置,不重试。

4.5 避坑指南

  • 我曾经在子线程里调init,结果SDK内部回调抛了Handler相关异常。后来发现init方法必须在主线程执行,SDK内部会做线程检查,但早期的版本不会,踩过一次坑。
  • 参数校验别偷懒。secretKey传入空字符串或者null,SDK启动时不会马上报错,直到第一次请求签名才挂掉。我建议初始化前自己做一波预检:
if (TextUtils.isEmpty(config.getSecretKey()) || config.getSecretKey().length() < 32) {
    throw new IllegalArgumentException("secretKey不能为空且长度至少32位");
}
  • 生命周期别忘了配对。stop之后如果调用任何业务接口,SDK会返回errorCode=STATE_ERROR。我见过一个团队在Activity onDestroy里调了stop,又在Service的onStartCommand里调了start,结果状态错乱。记住:stop之后必须重新init才能再次start。
  • storagePath别乱填。默认路径是应用内部缓存目录,但有些需求要存到SD卡。如果填的错误路径没有读写权限,初始化不会报错,但数据共享时会无声无息地失败。

4.6 参数的最佳实践

这是我个人习惯的一组推荐配置,适合大多数线上环境:

参数推荐值理由
timeout10000~20000太短容易在弱网环境失败,太长又卡住用户操作
retryCount2~3超过3次容易导致雪崩,而且重试间隔建议指数退避
logLevelWARN线上用INFO日志量太大,DEBUG更不能开,WARN刚刚好抓到异常
enableEncrypttrue除非是纯内网测试环境,否则都该开启

嗯,还有个细节你可能没注意——serverUrl的最后有没有斜杠。早期版本要求末尾不能有斜杠,后来改成了兼容处理,但我还是习惯统一去掉斜杠,避免和内部URL拼接出双斜杠。

总结一下:初始化是SDK的门槛,参数填错或状态不对,后面所有操作都没法跑。先把参数表过一遍,再按生命周期图走一遍流程,最后加上预检代码——这么一套下来基本稳了。