Android的SystemUI应用,为用户提供查看最近使用应用的列表,当用户点击Switch按键时,PhoneWindowManager会拦截此次key事件,拦截后调用StatusBarManagerService 接口,StatusBarManagerService通过调用mBar(SystemUI 注册到StatusBarManagerService的Binder对象)通知SystemUI启动RecentsActivity显示最近使用应用的列表。
启动的大概流程图如下:
Recents的UI结构图
接下来就按照流程图简单的分析一下RecentsActivity的启动流程:
step1拦截key_Switch事件:
在key事件分发之前,会调用PhoneWindowManager的interceptKeyBeforeDispatching函数优先处理key事件.
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;
}
preloadRecentApps();主要是预加载流程,和启动流程关键点基本一致,感兴趣自行分析。
当收到swith事件,不是down事件时调用toggleRecentApps函数:
step 2 toggleRecentApps函数
private void toggleRecentApps() {
mPreloadedRecentApps = false; // preloading no longer needs to be canceled
try {
IStatusBarService statusbar = getStatusBarService();
if (statusbar != null) {
statusbar.toggleRecentApps();
}
}
这里直接调用StatusBarManagerService的toggleRecentApps函数。
step 3 StatusBarManagerService .toggleRecentApps()
public void toggleRecentApps() {
if (mBar != null) {
try {
mBar.toggleRecentApps();
} catch (RemoteException ex) {}
}
}
mBar 是SystemUI启动的时候,在BaseStatusBar Start函数中通过调用StatusBarManagerService 的registerStatusBar函数注册过来的如下:
mCommandQueue = new CommandQueue(this, iconList);
mBarService.registerStatusBar(mCommandQueue, iconList, switches, binders);
mBar 是一个(IStatusBar)binder代理对象,他的本地对象就是运行在SystemUI的mCommandQueue对象。
这样StatusBarManagerService 就通过mBar进程间调用调用到mCommandQueue的toggleRecentApps函数。
step 4 mCommandQueue. toggleRecentApps
public void toggleRecentApps() {
synchronized (mList) {
mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS);
mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null).sendToTarget();
}
}
这个函数只是发送了一个消息到主线程消息队列。最后处理该消息的代码如下:
mCallbacks.toggleRecentApps();
mCallbacks 是BaseStatusBar 在step3中初始化CommandQueue时传入this对象。
BaseStatusBar 又发送消息到消息队列。最后处理该消息的是BaseStatusBar 的toggleRecents函数。
Step5 BaseStatusBar. toggleRecents
protected void toggleRecents() {
if (mRecents !=