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

代码位于: 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 需要注册,那么看一下它的
Manifest.xml

          
            
          
        
如果通过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:
[Android] [SystemUI] Recent -- 最近任务的启动流程_第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 的调用地方:
[Android] [SystemUI] Recent -- 最近任务的启动流程_第2张图片
图2
可以看出是系统的一些服务和Manager 会在相应的时机调用这个toggleRecentApps()方法。
所以这条线是这样的:
  1.  系统在相应的时机(长按Home键......)调用  CommandQueue的toggleRecentApps(); 
  2.  CommandQueue的 toggleRecentApps(): 删除消息队列中的 what 为 MSG_TOGGLE_RECENT_APPS的所有消息,然后再发送一条what 为MSG_TOGGLE_RECENT_APPS 的消息;
  3.  CommandQueue的Handler 接收消息,调用handleMessage处理消息,对MSG_TOGGLE_RECENT_APPS的消息的处理方式是: mCallbacks.toggleRecentApps() ,即BaseStatusBar 的toggleRecentApps 方法;
  4. BaseStatusBar的toggleRecentApps:发送MSG_TOGGLE_RECENTS_PANEL的消息;
  5.  BaseStatusBar 的 mHandler 接收到消息,调用handlerMessage 处理:这里又调用了 toggleRecentsActivity() 方法;
  6.  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)广播









你可能感兴趣的:(android)