Android 7.0 SystemUI Recent浅析



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
最近Task模块
Recents extends SystemUI
start进行初始化



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BaseStatusBar中如下函数显示最近task
    protected void toggleRecents() {
        if (mRecents != null) {
            mRecents.toggleRecents(mDisplay);
        }
    }



mRecents = getComponent(Recents.class);


Recents.java->toggleRecents(Display display)
mImpl.toggleRecents(growTarget);


RecentsImpl.java
public void toggleRecents(int growTarget) {


里面有4种情况
                        // Launch the next focused task
                        EventBus.getDefault().post(new LaunchNextTaskRequestEvent());

// Notify recents to move onto the next task
                        EventBus.getDefault().post(new IterateRecentsEvent());

if (DEBUG) Log.d(TAG, "toggleRecents step3");
EventBus.getDefault().post(new ToggleRecentsEvent());

// Otherwise, start the recents activity
ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
startRecentsActivity(runningTask, isHomeStackVisible.value, true /* animate */,
growTarget);


最终调用RecentsImpl.java中的
    private void startRecentsActivity(ActivityOptions opts) {
        Intent intent = new Intent();
        intent.setClassName(RECENTS_PACKAGE, RECENTS_ACTIVITY);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
                | Intent.FLAG_ACTIVITY_TASK_ON_HOME);


        if (opts != null) {
            mContext.startActivityAsUser(intent, opts.toBundle(), UserHandle.CURRENT);
        } else {
            mContext.startActivityAsUser(intent, UserHandle.CURRENT);
        }
        EventBus.getDefault().send(new RecentsActivityStartingEvent());
    }
启动RecentsActivity.java
    public final static String RECENTS_PACKAGE = "com.android.systemui";
    public final static String RECENTS_ACTIVITY = "com.android.systemui.recents.RecentsActivity";




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

recent 列表画面


recents.xml
recents_task_view_header.xml 是 app icon和title部分,对应TaskViewHeader.java
recents_task_view_header_overlay.xml 


recents_empty.xml 没有recent app


RecentsView是recent的重要部分,显示最近app列表的,其中成员变量
private TaskStackView mTaskStackView;记录了全部的TaskViews,TaskView就是每个RecentApp
TaskView Override了onLongClick方法,作为拖动的入口
TaskView <---->Task
Task记录了对应的app intent等重要信息


onLongClick中有如下两句是处理事件的开始
            EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
            EventBus.getDefault().send(new DragStartEvent(mTask, this, mDownTouchPos));
*****************


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EventBus.Event


所有继承Event的类 extends EventBus.Event
src/com/android/systemui/recents/events/activity/*      ------>画面迁移相关事件
src/com/android/systemui/recents/events/ui/dragndrop/*  ------>拖拽相关事件
src/com/android/systemui/recents/events/ui/focus/*      ------>focus变更相关事件
src/com/android/systemui/recents/events/ui/*            ------>其他UI相关事件


onBusEvent
所有事件回调都是这个,只是事件类型不同




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
启动后Recent的隐藏


PhoneStatusBar中调用了disable
12-19 20:17:06.041 1624-1624/com.android.systemui D/PhoneStatusBar: disable: < EXPAND* icons alerts system_info BACK* HOME* RECENT* clock SEARCH* quick_settings >


RECENT*表示需要隐藏recent app画面
            if ((state1 & StatusBarManager.DISABLE_RECENT) != 0) {
                // close recents if it's visible
                mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
                mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
            }

接着调用BaseStatusBar中的
MSG_HIDE_RECENT_APPS
处理隐藏recents app的机能


             case MSG_HIDE_RECENT_APPS:
                 hideRecents(m.arg1 > 0, m.arg2 > 0);
                 break;


调用Recents中的hideRecents
调用RecentsImpl中的hideRecents
        EventBus.getDefault().post(new HideRecentsEvent(triggeredFromAltTab,
                triggeredFromHomeKey));
通过EventBus发送了一个HideRecentsEvent




RecentsActivity的public final void onBusEvent(HideRecentsEvent event)
接收到EventBus的事件并进行处理
    public final void onBusEvent(HideRecentsEvent event) {
        if (event.triggeredFromAltTab) {
            // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app
            if (!mIgnoreAltTabRelease) {
                dismissRecentsToFocusedTaskOrHome();
            }
        } else if (event.triggeredFromHomeKey) {
            dismissRecentsToHome(true /* animateTaskViews */);


            // Cancel any pending dozes
            EventBus.getDefault().send(mUserInteractionEvent);
        } else {
            // Do nothing
        }
    }


以Home键为例
调用dismissRecentsToHome
其实是通过EventBus发送事件DismissRecentsToHomeAnimationStarted并带着一个LaunchHomeRunnable
LaunchHomeRunnable中进行动画和startActivityAsUser(mLaunchIntent, opts.toBundle(), UserHandle.CURRENT);
这样就显示了Home Launcher


当然接收事件的有如下几个地方
RecentsView.java
    public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
SystemBarScrimViews.java
    public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
TaskStackView.java
    public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {

分别进行了不同的处理
归根结底都是要隐藏RecentsView




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
分屏处理--长按事件
DragStartEvent
接收此事件一共3处


RecentsView.java
    public final void onBusEvent(DragStartEvent event) {
这里隐藏了clear all button,显示DockState
RecentsViewTouchHandler.java
    public final void onBusEvent(DragStartEvent event) {
拖拽开始前的初始化处理,发送event DragStartInitializeDropTargetsEvent,寻找drop target
将dockstates添加到mVisibleDockStates中
           // Add the dock state drop targets (these take priority)
                TaskStack.DockState[] dockStates = getDockStatesForCurrentOrientation();
                for (TaskStack.DockState dockState : dockStates) {
                    registerDropTargetForCurrentDrag(dockState);
                    dockState.update(mRv.getContext());
                    mVisibleDockStates.add(dockState);
                }
getDockStatesForCurrentOrientation
可以获取到左右两个dock state
TaskStackView.java
    public final void onBusEvent(DragStartEvent event) {
创建针对此事件的TaskView的动画,动画包括Z-order,alpha,size等的变化,并执行动画
TaskViewTransform.java动画封装类




DragStartInitializeDropTargetsEvent
只有一处处理此事件
TaskStackView.java
    public final void onBusEvent(DragStartInitializeDropTargetsEvent event) {
        if (ssp.hasFreeformWorkspaceSupport()) {
            event.handler.registerDropTargetForCurrentDrag(mStackDropTarget);
            event.handler.registerDropTargetForCurrentDrag(mFreeformWorkspaceDropTarget);
        }
两个drop target
    mStackDropTarget
mFreeformWorkspaceDropTarget

DockState
其实就是左右两边可以放置拖动item的target


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
分屏处理--拖动事件
RecentsViewTouchHandler.java
case MotionEvent.ACTION_MOVE:
                        if (mLastDropTarget != currentDropTarget) {
                            mLastDropTarget = currentDropTarget;
                            EventBus.getDefault().send(new DragDropTargetChangedEvent(mDragTask,
                                    currentDropTarget));
                        }


DragDropTargetChangedEvent接收方有两个
RecentsView.java
    public final void onBusEvent(DragDropTargetChangedEvent event) {
移动clear all btn的位置,DockState变更大小,从两边变成占据半屏
TaskStackView.java
    public final void onBusEvent(DragDropTargetChangedEvent event) {



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
分屏处理--UP事件
RecentsViewTouchHandler的handleTouchEvent中


            case MotionEvent.ACTION_UP:
                    EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView,
                            !cancelled ? mLastDropTarget : null));


发送DragEndEvent
接收事件有5处
RecentsView.java
    public final void onBusEvent(final DragEndEvent event) {
判断是否拖动到DockState上
如果是--->隐藏dockstate
不是  --->dockstate恢复默认状态
对clear btn改变显示隐藏状态
RecentsViewTouchHandler.java
    public final void onBusEvent(DragEndEvent event) {
变量reset 
mDragRequested = false;
        mDragTask = null;
        mTaskView = null;
        mLastDropTarget = null;
SystemBarScrimViews.java
    public final void onBusEvent(final DragEndEvent event) {
隐藏nav bar scrims
TaskStackView.java
    public final void onBusEvent(final DragEndEvent event) {
移动taskview到最终位置
移动其他task到对应位置
TaskView.java
    public final void onBusEvent(DragEndEvent event) {




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

你可能感兴趣的:(android,android源码)