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

5、其他

这章节主要会讲mRecentTasks赋值的地方,截图的时机,一些重点方法等

5.1 mRecentTasks赋值

分别会在startActivity的过程中和重新resume时对mRecentTasks赋值,另外ActivityStack和AMS两者中的mRecentTasks是同一个,具体可以看源码分析

5.1.1 startActivity

其中startActivity这种情况的代码是:
文件:ActivityStackSupervisor.java

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,  
            boolean andResume, boolean checkConfig) throws RemoteException {  

        ...  

        if (andResume) {  
            // 见5.1.2
            stack.minimalResumeActivityLocked(r);  
        }  
        ...  

    }  

5.1.2 minimalResumeActivityLocked

文件:ActivityStack.java

    void minimalResumeActivityLocked(ActivityRecord r) {
        r.state = ActivityState.RESUMED;
        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)"
                + " callers=" + Debug.getCallers(5));
        mResumedActivity = r;
        r.task.touchActiveTime();
        // 赋值的代码
        mRecentTasks.addLocked(r.task);
        completeResumeLocked(r);
        mStackSupervisor.checkReadyForSleepLocked();
        setLaunchTime(r);
    }

将TaskRecord对象加入到mRecentTasks对象中

5.1.2 重新resume

文件:ActivityStack.java

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {  
    ...  
    // 给mRecentTasks赋值
    mRecentTasks.addLocked(next.task);  
    ...  
}  

5.2 截图的时机

截图的时机是在Activity onPause时完成的,首先找到onPause的代码:
文件:ActivityStack.java

    private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {

        ......

        // 见5.2.1 
        mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);
    }

5.2.1 ensureActivitiesVisibleLocked

文件:ActivityStackSupervisor.java

    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
            boolean preserveWindows) {
        // First the front stacks. In case any are not fullscreen and are in front of home.
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            final int topStackNdx = stacks.size() - 1;
            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                // 见5.2.2
                stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
            }
        }
    }

继续调用ActivityStack的ensureActivitiesVisibleLocked

5.2.2 ensureActivitiesVisibleLocked

文件:ActivityStack.java

    final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,  
            boolean preserveWindows) {  
        ...  
        makeInvisible(r, visibleBehind);  

        ...  
    }  

接着调用makeInvisible

    private void makeInvisible(ActivityRecord r, ActivityRecord visibleBehind) {

            ......            
            // 见5.2.3
            setVisible(r, false);

            ......
    }

5.2.3 setVisible

文件:ActivityStack.java

    private void setVisible(ActivityRecord r, boolean visible) {
        r.visible = visible;
        if (!visible && r.mUpdateTaskThumbnailWhenHidden) {
            // 更新TaskThumbnail,调用screenshotActivitiesLocked,才是真正截图的地方
            r.updateThumbnailLocked(r.task.stack.screenshotActivitiesLocked(r), null);
            r.mUpdateTaskThumbnailWhenHidden = false;
        }
        mWindowManager.setAppVisibility(r.appToken, visible);
        final ArrayList<ActivityContainer> containers = r.mChildContainers;
        for (int containerNdx = containers.size() - 1; containerNdx >= 0; --containerNdx) {
            ActivityContainer container = containers.get(containerNdx);
            container.setVisible(visible);
        }
        mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
    }

看到screenshotActivitiesLocked你应该就会感到很熟悉,之前讲获取缩略图时讲到过,这个是截图的方法,所以setVisible才是真正截图的地方

截图之后,会同过saveImage保存起来,你应该会有映像,在缩略图的获取那个章节中,setLastThumbnailLocked方法调用了该方法,接下来我们来看看saveImage方法

5.2.4 saveImage

文件:RecentTasks.java

    void saveImage(Bitmap image, String path) {
        // 见5.2.5 保存缩略图
        mTaskPersister.saveImage(image, path);
    }

5.2.5 保存缩略图

文件:TaskPersister.java

    void saveImage(Bitmap image, String filePath) {
        synchronized (this) {
            int queueNdx;
            for (queueNdx = mWriteQueue.size() - 1; queueNdx >= 0; --queueNdx) {
                final WriteQueueItem item = mWriteQueue.get(queueNdx);
                if (item instanceof ImageWriteQueueItem) {
                    ImageWriteQueueItem imageWriteQueueItem = (ImageWriteQueueItem) item;
                    if (imageWriteQueueItem.mFilePath.equals(filePath)) {
                        // replace the Bitmap with the new one.
                        imageWriteQueueItem.mImage = image;
                        break;
                    }
                }
            }
            if (queueNdx < 0) {
                mWriteQueue.add(new ImageWriteQueueItem(filePath, image));
            }
            if (mWriteQueue.size() > MAX_WRITE_QUEUE_LENGTH) {
                mNextWriteTime = FLUSH_QUEUE;
            } else if (mNextWriteTime == 0) {
                mNextWriteTime = SystemClock.uptimeMillis() + PRE_TASK_DELAY_MS;
            }
            // 可以看到保存的路径***
            if (DEBUG) Slog.d(TAG, "saveImage: filePath=" + filePath + " now=" +
                    SystemClock.uptimeMillis() + " mNextWriteTime=" +
                    mNextWriteTime + " Callers=" + Debug.getCallers(4));
            notifyAll();
        }

        yieldIfQueueTooDeep();
    }

看filePath可以的得知路径为:/data/system_ce/0/recent_images

5.3 布局

  • recent.xml –> 最近任务管理器的布局
    • RecentsView –> 显示最近任务列表的
      • private TaskStackView mTaskStackView –> 记录了所有的TaskView;每一个TaskView都代表了一个recent app,也就是一个任务;
        • TaskView中onLongClick是处理托动的方法,里面
          EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
          EventBus.getDefault().send(new DragStartEvent(mTask, this, mDownTouchPos));

          是处理事件的开始

5.4 事件处理

  • 一般事件的发出方为:TaskView和TaskStackView
  • 事件定义的路径为:frameworks/base/packages/SystemUI/src/com/android/systemui/recents/events

5.5 时序图

暂无

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值