本文流程基于Android 9.0
1. PhoneWindowManager的事件分发
PhoneWindowManager
处理点击事件的方法是interceptKeyBeforeDispatching()
。相应recents键的逻辑如下:
点击switch键
} else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
//不处于锁屏界面
if (!keyguardOn) {
//ACTION_DOWN并且只点了一次
if (down && repeatCount == 0) {
//预加载recent
preloadRecentApps();
} else if (!down) {
//当不处于ACTION_DOWN时,可能是up或者cancel
toggleRecentApps();
}
}
return -1;
}
2.调用StatusBarManagerService的preloadRecentApps
private void preloadRecentApps() {
mPreloadedRecentApps = true;
StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
if (statusbar != null) {
//调用statusbar的preloadRecentApps()
statusbar.preloadRecentApps();
}
}
这里的是statusbar是通过getStatusBarManagerInternal()获取的,getStatusBarManagerInternal()实现如下:
StatusBarManagerInternal getStatusBarManagerInternal() {
synchronized (mServiceAquireLock) {
if (mStatusBarManagerInternal == null) {
mStatusBarManagerInternal =
LocalServices.getService(StatusBarManagerInternal.class);
}
return mStatusBarManagerInternal;
}
}
那么通过LocalServices.getService()是怎么得到的呢?其实在StatusBarManagerService初始化的时候,就将StatusBarManagerInernal的实现加进了LocalService中。
/**
* Construct the service, add the status bar view to the window manager
*/
public StatusBarManagerService(Context context, WindowManagerService windowManager) {
mContext = context;
mWindowManager = windowManager;
LocalServices.addService(StatusBarManagerInternal.class, mInternalService);
LocalServices.addService(GlobalActionsProvider.class, mGlobalActionsProvider);
}
mInternalService的实现如下:
/**
* Private API used by NotificationManagerService.
*/
private final StatusBarManagerInternal mInternalService = new StatusBarManagerInternal() {
private boolean mNotificationLightOn;
// 接口其他一些方法的实现
@Override
public void toggleRecentApps() {
if (mBar != null) {
try {
mBar.toggleRecentApps();
} catch (RemoteException ex) {
}
}
}
@Override
public void setCurrentUser(int newUserId) {
if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId);
mCurrentUserId = newUserId;
}
@Override
public void preloadRecentApps() {
if (mBar != null)