android 6.0 SystemUI源码分析(3)-Recent Panel加载显示流程

本文深入探讨了Android 6.0中Recent Panel的实现,包括按键处理、Recent Apps的加载流程及RecentActivity的显示与隐藏机制。通过对源码的分析,读者可以理解其内部工作原理。
摘要由CSDN通过智能技术生成

1.Recent Panel按键处理流程

SystemUI有一个很重要的功能就是显示近期使用的app,方便用户点击使用。

手机长按HOME键或者点击Navigation Bar的近期任务栏虚拟键可以显示Recent Panel。

我这里手头上只有Android TV平台,并且也便于debug,所以讲讲收到Switch按键后,Recent Panel的显示流程。

KeyEvent.java中对于Switch按键的定义:
    /** Key code constant: App switch key.
     * Should bring up the application switcher dialog. */
    public static final int KEYCODE_APP_SWITCH      = 187;

从KeyCode的定义可以看到Recent Panel的作用是the application switcher dialog。

当KeyEvent给到WindowManagerService之前,会先给到PhoneWindowManager处理(给系统一次机会,去处理按键消息)。
在KeyEvent出队列时,会走到interceptKeyBeforeDispatching函数,因此对于KEYCODE_APP_SWITCH的处理,会在这里进行。

 /** {@inheritDoc} */
    @Override
    public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
    ....
    else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
            if (!keyguardOn) {
                if (down && repeatCount == 0) {
                    preloadRecentApps();
                } else if (!down) {
                    toggleRecentApps();
                }
            }
            return -1;
        }
在key down时,load最近使用的apps->preloadRecentApps();
在key up时,打开或关闭Recent Panel-> toggleRecentApps();


2.Recent Apps加载流程


在PhoneWindowManager里面开始执行preloadRecentApps()函数后,一步步调用,最终会call到我们熟悉的Recents.java,即最终是通过SystemUI去Reload Recent apps。
下面是这个函数的逻辑时序图:

预加载Recent Apps核心函数是Recents.java中的preloadRecentsInternal函数。
函数代码如下:
  void preloadRecentsInternal() {
        // Preload only the raw task list into a new load plan (which will be consumed by the
        // RecentsActivity) only if there is a task to animate to.
        ActivityManager.RunningTaskInfo topTask = mSystemServicesProxy.getTopMostTask();
        MutableBoolean topTaskHome = new MutableBoolean(true);
        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
        sInstanceLoadPlan = loader.createLoadPlan(mContext);
        if (topTask != null && !mSystemServicesProxy.isRecentsTopMost(topTask, topTaskHome)) {
            sInstanceLoadPlan.preloadRawTasks(topTaskHome.value);
            loader.preloadTasks(sInstanceLoadPlan, topTaskHome.value);
            TaskStack top = sInstanceLoadPlan.getAllTaskStacks().get(0);
            if (top.getTaskCount() > 0) {
                preCacheThumbnailTransitionBitmapAsync(topTask, top, mDummyStackView,
                        topTaskHome.value);
            }
        }
    }
函数主要做了如下几件事情:
1)获取当前运行的Task
ActivityManager.RunningTaskInfo topTask = mSystemServicesProxy.getTopMostTask();

 /** Returns the top task. */
    public ActivityManager.RunningTaskInfo getTopMostTask() {
        List<ActivityManager.RunningTaskInfo> tasks = getRunningTasks(1);
        if (tasks != null && !tasks.isEmpty()) {
            return tasks.get(0);
        }
        return null;
    }

  /** Returns a list of the running tasks */
    private List<ActivityManager.RunningTaskInfo> getRunningTasks(int numTasks) {
        if (mAm == null) return null;
        return mAm.getRunningTasks
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值