# 需求描述

提供给指定应用加锁机制,应用处于上锁状态时,启动该应用需要做解锁操作,否则不仅用户不能与之交互,其应用界面也不可见,包括在 SystemUI 的 Recent 界面,也不可见其缩略图。

# 入职接手的第一版架构

ActivityThread handleActivityResume 发送广播给应用锁的接收器,启动 UnlockService 去查询数据库判断是否当前启动的 Activity 所在应用是否是上锁状态。图我就不画了,那代码不值得投入时间画架构图。主要缺点有

  1. 监听应用启动,判断是否上锁状态耗时,被锁应用已经启动完毕,用户可见可能长达一秒钟后,UnlockActivity 才启动覆盖在上面。
  2. UnlockActivity & 上锁状态的 Activity 不在同一个 ActivityTask,UnlockActivity 界面按 back,只能强制显示 Launcher,而不是上一个 Activity。
  3. 应用锁数据并没有提供 API 给 SystemUI。

# 第二版重构架构


在 AMS 的 AppLock 模块,绑定 AppLock 的 Service,并保持连接,Activity 的启动事件都通知给 AppLock。AppLock 实现 ContentProvider 对外提供数据访问 API,以此解决第一版 1 & 3 问题。
遗留缺点:

  1. 对于需要登陆等操作的互联网应用,会启动 MainActivity 后,判断是跳转登陆 Activity,由于连续启动两个上锁状态的 Activity,两个 UnlockActivity 也随之而来,屏幕闪缩。对此,可以单独为 MainActivity 加入过滤列表,不检测上锁解决,但这并非是好的方案。

# 第三版重构架构


开机后,读取并监听应用锁的数据,(主要是应用是否是上锁状态),应用启动后,在 AMS 检测是否上锁状态,将 Intent 保留在 IntentSender,原始 Intent 篡改为启动 UnlockActivity 的 Intent,制定当前 ActivityTask 启动 UnlockActivity,如此移花接木。解锁后,从 Intent 取出 IntentSender 重新发送请求给 AMS。至此,应用锁几乎完美无缺,久经测试同学的诸多考验。