android7.0 去电流程,Android7.0 apptransition主要流程

最近由于工作上的需要,结合一些大神的相关博客与Android源码,大概的把WMS中的app Transition流程给熟悉了一遍,在此写下一些小结

app Transition的主要流程

app Transition代表activity组件的切换过程,启动或是退出activity都会执行app Transition,Android系统定义了多达十几种app Transition类型,这些类型定义在AppTransition.java中

app Transition的过程可以用下图表示。

d0c5b0565df5

image.png

在apptransition的过程中,当前的activity会被设置为pause状态,同时窗口也将被设置为invisible,而即将启动的activity被设置为resume状态,窗口设置为visible,这个窗口切换的过程会以动画的形式执行,主要涉及的系统服务有AMS和WMS,本文只讨论窗口切换相关的流程,即WMS部分,AMS的不做涉及。

App Transition的核心步骤是定义在WindowManagerService.java中的3个函数完成,这些函数是随着activity的启动流程而逐步执行的。

public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {…}

通知wms准备窗口切换操作, transit代表具体的切换类型

public void setAppVisibility(IBinder token, boolean visible) {…}

设置activity窗口的可见性

public void executeAppTransition() {…}

执行窗口切换操作,具体的内容是窗口刷新,根据之前的transit参数选择对应的切换动画并播放

可以用一个流程图表示这一过程

d0c5b0565df5

image.png

我们来一一分析这几个重要的函数

prepareAppTransition

WindowManagerService.java

public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {

if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,

"prepareAppTransition()")) {

throw new SecurityException("Requires MANAGE_APP_TOKENS permission");

}

synchronized(mWindowMap) {

boolean prepared = mAppTransition.prepareAppTransitionLocked(

transit, alwaysKeepCurrent);

if (prepared && okToDisplay()) {

mSkipAppTransitionAnimation = false;

}

}

}

这个函数的核心是调到了AppTransition.java中的prepareAppTransitionLocked函数,我们来看看具体实现

AppTransition.java

boolean prepareAppTransitionLocked(int transit, boolean alwaysKeepCurrent) {

if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Prepare app transition:"

+ " transit=" + appTransitionToString(transit)

+ " " + this

+ " alwaysKeepCurrent=" + alwaysKeepCurrent

+ " Callers=" + Debug.getCallers(3));

if (!isTransitionSet() || mNextAppTransition == TRANSIT_NONE) {

setAppTransition(transit);

} else if (!alwaysKeepCurrent) {

if (transit == TRANSIT_TASK_OPEN && isTransitionEqual(TRANSIT_TASK_CLOSE)) {

// Opening a new task always supersedes a close for the anim.

setAppTransition(transit);

} else if (transit == TRANSIT_ACTIVITY_OPEN

&& isTransitionEqual(TRANSIT_ACTIVITY_CLOSE)) {

// Opening a new activity always supersedes a close for the anim.

setAppTransition(transit);

}

}

boolean prepared = prepare();

if (isTransitionSet()) {

mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);

mService.mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, APP_TRANSITION_TIMEOUT_MS);

}

return prepared;

}

其中mNextAppTransition 代表了将要执行的activity组件切换类型,此函数做了这么几件事:

1.如果mNextAppTransition 没有被设置或是设置为TRANSIT_NONE的话,就设置为参数所代表的activity组件切换类型

2.如果mNextAppTransition 已经被设置并且不要求保持mNextAppTransition不变的话,open activity和open task的优先级要高于close activity和close task,前者会覆盖后者

3.执行prepare()函数,返回结果prepared代表app Transition是否已经准备完成

4.向WMS发送一个延时5秒的消息,强制app Transition在5秒内完成

setAppVisibility

如前面流程图所说,这个函数的主要功能是设置窗口的可见性并触发窗口的relayout,这个函数比较长,我们只看关键的部分

WindowManagerService.java

public void setAppVisibility(IBinder token, boolean visible) {

synchronized(mWindowMap) {

wtoken = findAppWindowToken(token); // 1. 通过IBinder对象token找到wtoken(AppWindowToken对象,代表对应的activity窗口)

......

mOpeningApps.remove(wtoken);

mClosingApps.remove(wtoken); // 2. 把wtoken从mOpeningApps和mClosingApps两个ArraySet中移除

wtoken.hiddenRequested = !visible; // 3. 重新设置wtoken的可见性

......

if (okToDisplay() && mAppTransition.isTransitionSet()) {.

......

wtoken.mAppAnimator.setDummyAnimation(); // 4. 给wtoken先设置一个哑动画,等待具体执行时再设置合适的动画

......

if (visible) { // 5. 根据参数visible选择将wtoken重新加入mOpeningApps或是mClosingApps

mOpeningApps.add(wtoken);

} else {

mClosingApps.add(wtoken);

}

......

return;

}

......

// 6. 通知上层应用窗口的可见性变化(最终传递到ViewRootImpl并触发窗口的布局)

setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET, true, wtoken.voiceInteraction);

wtoken.updateReportedVisibilityLocked(); // 7. 通知AMS窗口的可见性变化

}

}

用于设置窗口可见性的函数是setTokenVisibilityLocked,我们后面还会相信分析,现在有个印象即可

executeAppTransition

executeAppTransition是完成前面的步骤后最终执行app Transition的函数

WindowManagerService.java

public void executeAppTransition() {

if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,

"executeAppTransition()")) {

throw new SecurityException("Requires MANAGE_APP_TOKENS permission");

}

synchronized(mWindowMap) {

if (DEBUG_APP_TRANSITIONS) Slog.w(TAG_WM, "Execute app transition: " + mAppTransition

+ " Callers=" + Debug.getCallers(5));

if (mAppTransition.isTransitionSet()) {

mAppTransition.setReady();

final long origId = Binder.clearCallingIdentity();

try {

mWindowPlacerLocked.performSurfacePlacement();

} finally {

Binder.restoreCallingIdentity(origId);

}

}

}

}

从代码中不难看出,executeAppTransition是刷新系统UI,在这个过程中会完成窗口可见性变化,窗口动画的设置和播放等过程,具体的流程放到下一篇文章分析

app Transition时序图

用一张时序图总结一下上面的流程

d0c5b0565df5

image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值