TaskSnapShot源码分析

本文详细分析了Android设备如何在每次应用切换时截取应用界面,并保存到内存和闪存中,以便在最近任务和关机重启后展示。主要涉及TaskSnapshotController、SurfaceControl以及TaskSnapshotPersister等关键组件的实现,同时也讨论了内存占用和效率问题。
摘要由CSDN通过智能技术生成

功能

在android设备上,

  1. 打开最近任务,会显示退出app时的界面
  2. 关机重启后马上打开最近任务,还是会显示关机前的app列表

Android为了实现上述的功能, 在每次app切换时都会对app界面进行截屏操作,截屏内容保存到内存和flash

代码分析

下面就从源码层面分析上面俩功能是如何实现的

主框架代码

TaskSnapshotController类在每次app切换时开始工作:

frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java
...
void onTransitionStarting(DisplayContent displayContent) {
	handleClosingApps(displayContent.mClosingApps); // 正准备关闭的app
}
private void handleClosingApps(ArraySet<ActivityRecord> closingApps) {
    if (shouldDisableSnapshots()) {
        return;
    }
    // We need to take a snapshot of the task if and only if all activities of the task are
    // either closing or hidden.
    getClosingTasks(closingApps, mTmpTasks);
    snapshotTasks(mTmpTasks); // 这里开始对即将退出的app界面做截屏操作
    mSkipClosingAppSnapshotTasks.clear();
}
...

下面snapshotTasks函数遍历所有正要关闭的task,对每一个符合条件的task执行snapshotTask()函数得到一个snapshot对象, snapshot对象会保存到内存中和flash中:

  1. 内存中保存的snapshot用于最近任务里,显示出每个app的界面
  2. flash中的截图,用于手机重启后打开最近任务时,显示关机前的没有关闭的所有app的界面
frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java
181      private void snapshotTasks(ArraySet<Task> tasks, boolean allowSnapshotHome) {
182          for (int i = tasks.size() - 1; i >= 0; i--) {
183              final Task task = tasks.valueAt(i);
184              final TaskSnapshot snapshot;
185              final boolean snapshotHome = allowSnapshotHome && task.isActivityTypeHome();
186              if (snapshotHome) {
187                  snapshot = snapshotTask(task);
188              } else {
189                  switch (getSnapshotMode(task)) {
190                      case SNAPSHOT_MODE_NONE:
191                          continue;
192                      case SNAPSHOT_MODE_APP_THEME:
193                          snapshot = drawAppThemeSnapshot(task);
194                          break;
195                      case SNAPSHOT_MODE_REAL:
196                          snapshot = snapshotTask(task); // 得到task的截图
197                          break;
198                      default:
199                          snapshot = null;
200                          break;
201                  }
202              }
203              if (snapshot != null) {
204                  final GraphicBuffer buffer = snapshot.getSnapshot();
205                  if (buffer.getWidth() == 0 || buffer.getHeight() == 0) {
206                      buffer.destroy();
207                      Slog.e(TAG, "Invalid task snapshot dimensions " + buffer.getWidth() + "x"
208                              + buffer.getHeight());
209                  } else {
210                      mCache.putSnapshot(task, snapshot); // task截图保存到缓存中
211                      // Don't persist or notify the change for the temporal snapshot.
212                      if (!snapshotHome) {
213                          mPersister.persistSnapshot(task.mTaskId, task.mUserId, snapshot); // 截图保存到flash中
214                          task.onSnapshotChanged(snapshot); // 通知截图有变化
215                      }
216                  }
217              }
218          }
219      }

获取task截图的具体实现:

398      TaskSnapshot snapshotTask(Task task, int pixelFormat) {
399          TaskSnapshot.Builder builder = new TaskSnapshot.Builder();
400  
401          if (!prepareTaskSnapsh
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值