在前面讨论TaskSnapshot的时候,
https://blog.csdn.net/aaajj/article/details/114208770
我们知道
TaskSnapshotController中也通过获取layer的方式获取了graphicBuffer,这样按recent按键的时候就可以看到每个应用的快照截图,
并且保存了图像信息到手机data/system_ce/0/snapshots中,这样,手机重启后,点击recent任务按键,还可以看到关机前的任务快照截图
这里我们来看看其写graphicBuffer对象数据到图片的实现,
在frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java
中,有
168 void snapshotTasks(ArraySet<Task> tasks) {
169 for (int i = tasks.size() - 1; i >= 0; i--) {
170 final Task task = tasks.valueAt(i);
171 final int mode = getSnapshotMode(task);
172 final TaskSnapshot snapshot;
173 switch (mode) {
174 case SNAPSHOT_MODE_NONE:
175 continue;
176 case SNAPSHOT_MODE_APP_THEME:
177 snapshot = drawAppThemeSnapshot(task);
178 break;
179 case SNAPSHOT_MODE_REAL:
180 snapshot = snapshotTask(task);
181 break;
182 default:
183 snapshot = null;
184 break;
185 }
186 if (snapshot != null) {
187 final GraphicBuffer buffer = snapshot.getSnapshot();
188 if (buffer.getWidth() == 0 || buffer.getHeight() == 0) {
189 buffer.destroy();
190 Slog.e(TAG, "Invalid task snapshot dimensions " + buffer.getWidth() + "x"
191 + buffer.getHeight());
192 } else {
193 mCache.putSnapshot(task, snapshot);
194 mPersister.persistSnapshot(task.mTaskId, task.mUserId, snapshot);
195 if (task.getController() != null) {
196 task.getController().reportSnapshotChanged(snapshot);
197 }
198 }
199 }
200 }
201 }
mPersister.persistSnapshot(task.mTaskId, task.mUserId, snapshot);
方法进行了数据保存
frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
101 void persistSnapshot(int taskId, int userId, TaskSnapshot snapshot) {
102 synchronized (mLock) {
103 mPersistedTaskIdsSinceLastRemoveObsolete.add(taskId);
104 sendToQueueLocked(new StoreWriteQueueItem(taskId, userId, snapshot));
105 }
106 }
275 StoreWriteQueueItem(int taskId, int userId, TaskSnapshot snapshot) {
276 mTaskId = taskId;
277 mUserId = userId;
278 mSnapshot = snapshot;
279 }
280
最后调用到write方法
338 boolean writeBuffer() {
339 final Bitmap bitmap = Bitmap.createHardwareBitmap(mSnapshot.getSnapshot());
340 if (bitmap == null) {
341 Slog.e(TAG, "Invalid task snapshot hw bitmap");
342 return false;
343 }
344
345 final Bitmap swBitmap = bitmap.copy(Config.ARGB_8888, false /* isMutable */);
346 final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId);
347 final Bitmap reduced = mSnapshot.isReducedResolution()
348 ? swBitmap
349 : Bitmap.createScaledBitmap(swBitmap,
350 (int) (bitmap.getWidth() * REDUCED_SCALE),
351 (int) (bitmap.getHeight() * REDUCED_SCALE), true /* filter */);
352 try {
353 FileOutputStream reducedFos = new FileOutputStream(reducedFile);
354 reduced.compress(JPEG, QUALITY, reducedFos);
355 reducedFos.close();
356 } catch (IOException e) {
357 Slog.e(TAG, "Unable to open " + reducedFile +" for persisting.", e);
358 return false;
359 }
360
361 // For snapshots with reduced resolution, do not create or save full sized bitmaps
362 if (mSnapshot.isReducedResolution()) {
363 return true;
364 }
365
366 final File file = getBitmapFile(mTaskId, mUserId);
367 try {
368 FileOutputStream fos = new FileOutputStream(file);
369 swBitmap.compress(JPEG, QUALITY, fos);
370 fos.close();
371 } catch (IOException e) {
372 Slog.e(TAG, "Unable to open " + file + " for persisting.", e);
373 return false;
374 }
375 return true;
376 }
377 }
Bitmap中,通过
Bitmap bitmap = Bitmap.createHardwareBitmap(mSnapshot.getSnapshot());
来把GraphicBuffer数据转换为Bitmap对象,
再通过调用compress方法保存到图片文件中。