SWE / Android · System / Mobile Design

Meta Android照片上传库:持久队列、分片与取消

设计可供宿主应用调用的照片上传SDK,明确生命周期、离线重试、断点续传和事件回调。

题目重点:设计可供宿主应用调用的照片上传SDK,明确生命周期、离线重试、断点续传和事件回调。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练SDK接口enqueue(uri,options)→taskId、observe(taskId)、cancel(taskId),认证/选择媒体/用户授权由宿主协作,库不自作主张读取整个相册。
  • 任务要在进程终止后可恢复,实际媒体URI访问权限、目标Android版本和后台策略必须确认。本文给设计和状态,不假称所有设备都允许即时后台执行。

解题路线

  1. 把模块分为UploadFacade、TaskStore、SchedulerAdapter、MediaReader、Transport与ProgressStream;宿主注入认证、网络/政策与日志,避免SDK持有Activity造成泄漏。task metadata持久化,回调订阅随生命周期解除。
  2. 状态QUEUED→PREPARING→UPLOADING→COMMITTING→SUCCEEDED或FAILED/CANCELLED;attempt独立,terminal状态不被旧回调覆盖。业务taskId稳定,transport uploadSessionId可因服务端过期更新。
  3. 服务端创建session给chunkSize,上传带(chunkIndex,hash,idempotencyKey),客户端存已确认chunks。finish提交manifest并由服务器校验全部内容hash,确认成功后才UI显示完成,不因发送bytes到100%就提前报成功。
  4. 离线/服务器临时失败采用有上限backoff;认证失败请求宿主刷新/交互,URI失权不可盲目重试。Android持久可延后工作可由WorkManager适配网络等约束和retry;它不是精确时刻触发器,约束变化/重启会影响执行时机。
  5. cancel标记版本并取消在途请求,迟到chunk成功可保留服务端孤儿session由清理回收,但不能让已取消任务再显示SUCCEEDED。按租户/用户隔离session,退出账号停止任务并避免token复用。

手动走一遍

照片9MB、chunk4MB需要3块。第2块上传成功但ACK丢失,重试同hash/index应得到已存在结果;若重新create整个文件可能重复媒体。宿主页面旋转只换观察者,不新建同一次task。

规模与取舍

并发C任务、每任务缓冲chunkSize,buffer约C×chunkSize,不能每图全解码后持有大bitmap。吞吐受网络/电量/内存与服务器限制;progress节流减少UI更新,SDK边界独立测试生命周期与网络失败。

易错点与追问

容易失分的边界

  • 全局单例持有Activity或回调会泄漏页面。
  • WorkManager持久调度不能保证任意后台即时执行;不得用它承诺每次触发都准时。
  • 重复enqueue若同一次用户操作需idempotencyKey,文件hash相同是否合并则是另一个产品规则。

继续深挖

  • 直接上传与分片上传阈值如何选?依据文件大小、失败率与服务器协议,量测而非固定拍脑袋。
  • URI来自短期授权而需跨重启上传时,宿主与库如何协商持久访问或安全复制?

技术参考

✓已复制微信号!