Andorid N 最近任务管理器流程详解(三)

3. 缩略图的获取

本章节主要讲一下缩略图的获取

3.1 获取或者更新缩略图

文件:RecentsTaskLoader.java

    Bitmap getAndUpdateThumbnail(Task.TaskKey taskKey, boolean loadIfNotCached) {
        SystemServicesProxy ssp = Recents.getSystemServices();

        // 如果key存在,则返回缩略图的缓存
        ThumbnailData thumbnailData = mThumbnailCache.getAndInvalidateIfModified(taskKey);
        if (thumbnailData != null) {
            return thumbnailData.thumbnail;
        }

        if (loadIfNotCached) {
            RecentsConfiguration config = Recents.getConfiguration();
            if (config.svelteLevel < RecentsConfiguration.SVELTE_DISABLE_LOADING) {
                // 见3.2 从系统中获取thumbnail
                thumbnailData = ssp.getTaskThumbnail(taskKey.id);
                if (thumbnailData.thumbnail != null) {
                    mThumbnailCache.put(taskKey, thumbnailData);
                    return thumbnailData.thumbnail;
                }
            }
        }
        // 没有装载任何缩略图
        return null;
    }

Task的key是有效的,那就返回缩略图的缓存,否则重新获得缩略图,并存储

3.2 从系统中获取缩略图

文件:SystemServiceProxy.java

    public ThumbnailData getTaskThumbnail(int taskId) {
        if (mAm == null) return null;
        ThumbnailData thumbnailData = new ThumbnailData();

        ......

        // 见3.3 获取task thumbnail
        getThumbnail(taskId, thumbnailData);
        if (thumbnailData.thumbnail != null) {
            thumbnailData.thumbnail.setHasAlpha(false);
            // We use a dumb heuristic for now, if the thumbnail is purely transparent in the top
            // left pixel, then assume the whole thumbnail is transparent. Generally, proper
            // screenshots are always composed onto a bitmap that has no alpha.
            if (Color.alpha(thumbnailData.thumbnail.getPixel(0, 0)) == 0) {
                mBgProtectionCanvas.setBitmap(thumbnailData.thumbnail);
                mBgProtectionCanvas.drawRect(0, 0, thumbnailData.thumbnail.getWidth(),
                        thumbnailData.thumbnail.getHeight(), mBgProtectionPaint);
                mBgProtectionCanvas.setBitmap(null);
                Log.e(TAG, "Invalid screenshot detected from getTaskThumbnail()");
            }
        }
        return thumbnailData;
    }

根据task id返回top task thumbnail

3.3 获取task thumbnail

文件:SystemServicesProxy.java

    public void getThumbnail(int taskId, ThumbnailData thumbnailDataOut) {
        if (mAm == null) {
            return;
        }
        // 见3.4 
        ActivityManager.TaskThumbnail taskThumbnail = mAm.getTaskThumbnail(taskId);
        if (taskThumbnail == null) {
            return;
        }

        ......

    }

从Activity manager返回一个任务缩略图

3.4 getTaskThumbnail

通过binder调用,我们知道最后会调用AMS的getTaskThumbnail
文件:ActivityManagerService.java

    @Override
    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
        synchronized (this) {
            // 首先要检查权限,必须有READ_FRAME_BUFFER权限
            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
                    "getTaskThumbnail()");
            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
            if (tr != null) {
                // 见3.5 根据ID找到栈,然后获取缩略图
                return tr.getTaskThumbnailLocked();
            }
        }
        return null;
    }

3.5 根据ID找到栈,然后获取缩略图

文件:TaskRecord.java

    public TaskThumbnail getTaskThumbnailLocked() {
        if (stack != null) {
            final ActivityRecord resumedActivity = stack.mResumedActivity;
            if (resumedActivity != null && resumedActivity.task == this) {
                // 准备去截图
                final Bitmap thumbnail = stack.screenshotActivitiesLocked(resumedActivity);
                setLastThumbnailLocked(thumbnail);
            }
        }
        final TaskThumbnail taskThumbnail = new TaskThumbnail();
        // 见3.6
        getLastThumbnail(taskThumbnail);
        return taskThumbnail;
    }

除了栈顶正在显示的TaskRecord会去实时的截取屏幕图像,其他走的是getLastThumbnail

3.6 getLastThumbnail

文件:TaskRecord.java

    void getLastThumbnail(TaskThumbnail thumbs) {
        thumbs.mainThumbnail = mLastThumbnail;
        thumbs.thumbnailInfo = mLastThumbnailInfo;
        thumbs.thumbnailFileDescriptor = null;
        if (mLastThumbnail == null) {
            thumbs.mainThumbnail = mService.mRecentTasks.getImageFromWriteQueue(
                    mLastThumbnailFile.getAbsolutePath());
        }
        // Only load the thumbnail file if we don't have a thumbnail
        if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) {
            try {
                thumbs.thumbnailFileDescriptor = ParcelFileDescriptor.open(mLastThumbnailFile,
                        ParcelFileDescriptor.MODE_READ_ONLY);
            } catch (IOException e) {
            }
        }
    }

这里是去读取缩略图,这些缩略图的保存位置在:/data/system_ce/0/recent_images文件夹

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值