[Android] [SystemUI] Recent -- 最近任务的启动流程
16lz
2021-01-26
代码位于: 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 隐式启动的话,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)广播
更多相关文章
- Android(安卓)GLSurfaceView.Renderer 类 onDrawFrame 方法的刷
- Android(安卓)Camera的代码结构
- Android(安卓)4.0 +MyEclipse 9 整合开发环境搭建
- 【Android学习笔记】Android中Intent的应用方法探索
- AndroidManifest.xml中的android:exported属性
- Android中notifyDataSetInvalidated()和notifyDataSetChanged()
- JNI中调用JAVA各种方法详解
- Intent和Intent-Filter详解
- Android(安卓)开发学习小结(五)