Android N进入分屏代码分析二

在上一篇文章中已经讲解了第一步,从PhoneStatusBar.java到Recents.java的流程,如果有需要可以点击上一篇
在Recents.java中讲解了当我们调用dockTopTask(…)函数时会判断条件,如果可以进入分屏且是systemuser时,就跳转到RecentsImpl.dockTopTask(…)函数中。
    public void dockTopTask(int topTaskId, int dragMode,
            int stackCreateMode, Rect initialBounds) {
        SystemServicesProxy ssp = Recents.getSystemServices();

        // Make sure we inform DividerView before we actually start the activity so we can change
        // the resize mode already.
        if (ssp.moveTaskToDockedStack(topTaskId, stackCreateMode, initialBounds)) {
            EventBus.getDefault().send(new DockedTopTaskEvent(dragMode, initialBounds));
            showRecents(
                    false /* triggeredFromAltTab */,
                    dragMode == NavigationBarGestureHelper.DRAG_MODE_RECENTS,
                    false /* animate */,
                    true /* launchedWhileDockingTask*/,
                    false /* fromHome */,
                    DividerView.INVALID_RECENTS_GROW_TARGET);
        }
    }
代码位置:framework/base/packages/SystemUI/…/RecentsImpl.java

介绍下参数:
- topTaskId:就是获取的进入分屏应用的taskID,这个id是唯一的,可以用来区别app
- dragMode :NavigationBarGestureHelper.DRAG_MODE_NONE
- stackCreateMode : ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
- initialBounds: 全屏大小,例如当前机器分辨率是1920*1200,那么这个值就是(0, 0, 1920,1200)

SystemServicesProxy ssp = Recents.getSystemServices();
ssp.moveTaskToDockedStack(topTaskId, stackCreateMode, initialBounds)
这里是通过分屏应用的taskid,把应用由当前的stack移动到dockstack中,这部分内容在后续介绍分屏的services中会详细介绍,这里只做简单说明。

流程图:

Created with Raphaël 2.1.0 开始 移动当前task到dockstack 移动成功? 显示滑动分界线 显示任务记录列表 结束 yes no

介绍一下AndroidN上SystemUI在不同类之间传递消息的方式之一:
EventBus.getDefault().send(new xxxEvent(...));
public final void onBusEvent(xxxEvent event) {}
这两个一定是成对出现,xxxEvent必须一致,这样就可以在不同的类之间传递消息,这样就简化很多,而且可以做到发送一次,多各类都能接收到消息,不需要像之前一样写接口。
但是想使用这种方式在类中也是需要注册的,只有按照下图的方式注册过,才能接收到消息,否则是无效的。
    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        EventBus.getDefault().unregister(this);
    }
我们也可以扩展消息,可以在framework/base/packages/SystemUI/src/com/android/systemui/recents/events/activity/下添加对应的类

当移动task完成后,发送消息EventBus.getDefault().send(new DockedTopTaskEvent(dragMode, initialBounds));

在DividerView.java中有public final void onBusEvent(DockedTopTaskEvent event) {…}接收到消息,更新状态,主要是把mDockedRect改为全屏大小,这里显示的区域是进入分屏应用的区域。

接下来启动RecentActivity,在RecentsActivity中的onStart()方法中:
  • EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));通知PhoneStatusBar,RecentsActivity显示了,改变状态
  • mRecentsView.getViewTreeObserver().addOnPreDrawListener(mRecentsDrawnEventListener);这里是重点,mRecentsDrawnEventListener在注册监听后,就会发送消息EventBus.getDefault().post(new RecentsDrawnEvent());告诉DividerView去修改进入分屏应用的bounds
DividerView接收到消息:public final void onBusEvent(RecentsDrawnEvent drawnEvent) {…}
  • mState.animateAfterRecentsDrawn:true
  • mState.growAfterRecentsDrawn:false
点击Recents键最小化分屏时,两个值都是false。
stopDragging(…)中设置要滑动的位置,在flingTo(…)滑动到指定的位置,Android在制作这块时考虑到了界面的美化,使用了ValueAnimator来逐步修改bounds,没有很粗暴的一步修改到位。(android N上有大量java Lambda 表达式的写法,如果不熟悉可以看些文档)。当位置修改到中间位置时,进入分屏和RecentsActivity两个应用都显示出来。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值