您的位置:首页 > 产品设计 > UI/UE

[置顶] [Android] [SystemUI] Recent -- 最近任务的启动流程

2014-06-12 14:55 771 查看
代码位于: com.android.systemui.recent

工具: eclipse

主要问题:

1. 启动方式

2. 怎么显示最近任务?布局结构,数据来源。

3. 如何删除?删除后执行哪些动作?

1. 启动方式

很自然地找到 com.andorid.systemui.recent.RecentsActivity ,然后 ctrl+alt+g 搜索引用,除去recent 中出现的,主要有两处:1. Manifest.xml ; 2. BaseStatusBar 
1) Manifest.xml中肯定是有的,Activity 需要注册,那么看一下它的<intent-filter>:
Manifest.xml

<activity android:name=".recent.RecentsActivity"
android:label="@string/accessibility_desc_recent_apps"
android:theme="@style/RecentsStyle"
android:excludeFromRecents="true"
android:launchMode="singleInstance"
android:exported="true">
<intent-filter>
<action android:name="com.android.systemui.TOGGLE_RECENTS" />
</intent-filter>
</activity>
如果通过intent 隐式启动的话,action 为 com.android.systemui.TOGGLE_RECENTS,所以搜索这个字符串--没有记过,那么就是显式启动,于是搜 com.andorid.systemui.recent.RecentsActivity或者RecentsActivity,找到了toggleRecentsActivity, 于是直接看toggleRecentsActivity。

2) BaseStatusBar 中的主要是一个 一个方法:toggleRecentsActivity, 有如下代码:
BaseStatusBar toggleRecentsActivity

Intent intent = new Intent(RecentsActivity.TOGGLE_RECENTS_INTENT);
intent.setClassName("com.android.systemui",
"com.android.systemui.recent.RecentsActivity");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);

if (firstTask == null) {
if (RecentsActivity.forceOpaqueBackground(mContext)) {
ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
R.anim.recents_launch_from_launcher_enter,
R.anim.recents_launch_from_launcher_exit);
mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
UserHandle.USER_CURRENT));
} else {
// The correct window animation will be applied via the activity's style
mContext.startActivityAsUser(intent, new UserHandle(
UserHandle.USER_CURRENT));
}

}
可以确认是通过 toggleRecentsActivity 方法启动的了,于是接下来找toggleRecentsActivity 方法怎么被调用。
BaseStatusBar.toggleRecentsActivity
protected class H extends Handler {
public void handleMessage(Message m) {
Intent intent;
switch (m.what) {
case MSG_TOGGLE_RECENTS_PANEL:
if (DEBUG) Slog.d(TAG, "toggle recents panel");
if(!mSuperPowerSave){
toggleRecentsActivity();
}
break;
在一个Handler 中,接受到一个what 为 MSG_TOGGLE_RECENTS_PANEL 的消息后,就会启动 RecentActivity ,再看:(A)这个消息什么时候被发送(B)该Handler 对象在哪里

(A)这个消息什么时候被发送

在BaseStatusBar 中找到:
BaseStatusBar .toggleRecentApps

@Override
public void toggleRecentApps() {
int msg = MSG_TOGGLE_RECENTS_PANEL;
mHandler.removeMessages(msg);
mHandler.sendEmptyMessage(msg);
}
// ......
继续找 toggleRecentApps() ,结果如图1:



图1
可以看到有四个地方调用了,其中TableStatusBar 就不管了,看看其它三个调用分别是什么时机。
A1.handleMessage

com.android.systemui.statusbar.CommandQueue
private final class H extends Handler {
public void handleMessage(Message msg) {
final int what = msg.what & MSG_MASK;
switch (what) {
//......

case MSG_TOGGLE_RECENT_APPS:
mCallbacks.toggleRecentApps();
break;

//......
MSG_TOGGLE_RECENT_APPS消息又是怎么过来的了:
com.android.systemui.statusbar.CommandQueue

public void toggleRecentApps() {
synchronized (mList) {
mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS);
mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null).sendToTarget();
}
}
看toggleRecentApps 的调用地方:



图2
可以看出是系统的一些服务和Manager 会在相应的时机调用这个toggleRecentApps()方法。
所以这条线是这样的:

 系统在相应的时机(长按Home键......)调用  CommandQueue的toggleRecentApps(); 
 CommandQueue的 toggleRecentApps(): 删除消息队列中的 what 为 MSG_TOGGLE_RECENT_APPS的所有消息,然后再发送一条what 为MSG_TOGGLE_RECENT_APPS 的消息;
 CommandQueue的Handler 接收消息,调用handleMessage处理消息,对MSG_TOGGLE_RECENT_APPS的消息的处理方式是: mCallbacks.toggleRecentApps() ,即BaseStatusBar 的toggleRecentApps 方法;
BaseStatusBar的toggleRecentApps:发送MSG_TOGGLE_RECENTS_PANEL的消息;
 BaseStatusBar 的 mHandler 接收到消息,调用handlerMessage 处理:这里又调用了 toggleRecentsActivity() 方法;
 toggleRecentsActivity() :启动了RecentsActivity.

A2.onClick
onClick 所在之处的代码是一个onClickListener 对象:
private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
public void onClick(View v) {
toggleRecentApps();
}
};
//......

设置给导航栏的Recent按钮:
mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);


A3.onReceive
这个是PhoneStatusBar中注册的一个BroadCastReceive中onReceive 方法。

小结:
启动方式有三:1)系统启动,如长按Home键,系统的某些服务启动。2)导航栏按钮;3)广播
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: