RecentsActivity的启动分析一

本文详细探讨了用户点击切换按键启动RecentsActivity的过程。从PhoneWindowManager拦截事件开始,涉及预加载最近应用、toggleRecentApps方法,通过IStatusBarService与StatusBarManagerService交互,再到CommandQueue调用BaseStatusBar的toggleRecentApps方法,最终启动RecentsActivity,显示最近应用列表。整个流程涉及到SystemUI、StatusBarManagerService和Recents组件的交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RecentsActivity是SystemUI用于显示最近使用的应用列表,当用户点击Switch按键时会启动RecentsActivity。先分析启动的过程。

首先是用户点击SWITCH按键,PhoneWindowManager会在事件分发前先拦截该事件:

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;
    }
    ……
}

根据down标识分两种情况:

(1)preloadRecentApps();//预加载最近使用应用

private void preloadRecentApps() {
    mPreloadedRecentApps = true;
    try {
        IStatusBarService statusbar = getStatusBarService();
        if (statusbar != null) {
            statusbar.preloadRecentApps();
        }
    } catch (RemoteException e) {
        Slog.e(TAG, "RemoteException when preloading recent apps", e);
        // re-acquire status bar service next time it is needed.
        mStatusBarService = null;
    }
}

(2)toggleRecentApps();

private void toggleRecentApps() {
    mPreloadedRecentApps = false;
    try {
        IStatusBarService statusbar = getStatusBarService();
        if (statusbar != null) {
            statusbar.toggleRecentApps();
        }
    } catch (RemoteException e) {
        mStatusBarService = null;
    }
}

这两种情况都获取了IStatusBarService的对象statusbar,并由该对象调用preloadRecentApps()和toggleRecentApps()方法。IStatusBarService.aidl是一个aidl服务,aidl接口中的内部抽象类Stub是由StatusBarManagerService这个类来实现的。Stub类继承了Binder,并继承我们在aidl文件中定义的接口。

public class StatusBarManagerService extends IStatusBarService.Stub {
   
   

    private volatile IStatusBar mBar;

    @Override
    public void toggleRecentApps() {
        if (mBar != null) {
            try {
                mBar.toggleRecentApps();
            } catch (RemoteException ex) {}
        }
    }

    @Override
    public void preloadRecentApps() {
        if (mBar != null) {
            try {
                mBar.preloadRecentApps();
            } catch (RemoteException ex) {}
        }
    }

    @Override
    public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList,
            int switches[], List<IBinder> binders) {
        enforceStatusBarService();
        mBar = bar;
        ……
    }
}

mBar是IStatusBar的对象,IStatusBar.aidl接口中的内部抽象类Stub是由CommandQueue这个类实现的。

public class CommandQueue extends IStatusBar.Stub {
   
   
    /**
     * These methods are called back on the main thread.
     */
    public interface Callbacks {
   
   
       public void toggleRecentApps();
       public void preloadRecentApps(); 
    }
    /*这是IStatusBar.aidl文件定义的抽象方法的实现,通过mHandler将消息传递给主线程*/
    public void toggleRecentApps() {
        synchronized (mList) {
            mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS);
            mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null).sendToTarget();
        }
    }
     /*这是IStatusBar.aidl文件定义的抽象方法的实现*/
    public void 
### `RecentsActivity` 类的作用与功能 在 Android 系统中,`RecentsActivity` 是负责处理最近任务(Recent Apps)界面的核心类之。它主要管理用户点击“最近任务”按钮后显示的活动列表,并提供流畅的任务切换体验。该类通常继承自 `Activity` 或其子类,包含对动画、窗口过渡、数据加载等关键操作的支持。 #### 核心职责 - **启动最近任务界面**:当用户点击系统导航栏中的“最近任务”按钮时,`RecentsActivity` 会响应并启动相关 UI。 - **管理任务卡片**:包括加载应用缩略图、标题、包名等信息,并展示为可滑动的卡片形式。 - **支持窗口动画**:通过 `RemoteAnimationProvider` 实现平滑的窗口切换效果,提升用户体验[^1]。 - **监听用户交互事件**:如点击某个任务卡片以切换到对应的应用,或滑动清除任务。 - **资源释放与状态保存**:在 `onDestroy()` 和 `onSaveInstanceState()` 中处理内存回收和界面状态持久化。 ### 类结构与关键方法 ```java public class RecentsActivity extends Activity { // 初始化与生命周期相关方法 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.recents_activity_layout); // 设置布局文件 initializeComponents(); // 初始化组件如RecyclerView, TaskViewAdapter等 } private void initializeComponents() { // 初始化UI组件及数据源 mTaskViewAdapter = new TaskViewAdapter(this, getTaskList()); mRecyclerView.setAdapter(mTaskViewAdapter); } // 启动逻辑 public void startOverview(Intent intent) { startActivity(intent); // 使用Intent启动RecentsActivity [^2] overridePendingTransition(0, 0); // 自定义转场动画 } // 动画处理 public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets, RemoteAnimationTargetCompat[] wallpaperTargets) { // 创建窗口动画,例如卡片展开/折叠效果 return AnimationUtils.createCardSlideAnimator(appTargets); } // 清除任务 public void clearTask(int taskId) { ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); am.removeTask(taskId); // 调用系统服务移除指定任务 } } ``` #### 生命周期与资源管理 - `onCreate()`:初始化界面元素和数据模型。 - `onStart()` / `onResume()`:恢复动画播放或重新绑定数据。 - `onPause()` / `onStop()`:暂停动画或释放部分资源。 - `onDestroy()`:清理所有资源,避免内存泄漏。 ### 数据来源与任务管理 `RecentsActivity` 依赖于系统提供的 `ActivityManager` 获取当前设备上的任务列表。具体流程如下: 1. 调用 `ActivityManager.getRecentTasks()` 方法获取最近运行的任务信息。 2. 解析每个任务的 `Intent`、图标、标题等元数据。 3. 将解析后的数据封装成 `TaskInfo` 对象,并传递给适配器用于渲染 UI。 示例代码片段: ```java ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasks(20, ActivityManager.RECENT_IGNORE_UNAVAILABLE); for (ActivityManager.RecentTaskInfo task : recentTasks) { Drawable icon = getPackageManager().getApplicationIcon(task.baseIntent.getComponent().getPackageName()); String title = getPackageManager().getApplicationLabel( getPackageManager().getApplicationInfo(task.baseIntent.getComponent().getPackageName(), 0)).toString(); TaskInfo info = new TaskInfo(icon, title, task.id); taskList.add(info); } ``` ### 与其他组件交互 - **SystemUI 调用 Launcher3 的接口**:通过 `OverviewCommandHelper.run()` 方法触发 `RecentsActivity` 的启动逻辑。 - **远程动画支持**:使用 `RemoteAnimationProvider` 定义自定义动画行为,确保从其他界面切换到最近任务时具有统的视觉效果。 - **跨进程通信(IPC)机制**:利用 Binder 机制实现 SystemUI 与 Launcher3 之间的通信,从而协调手势操作、动画播放等复杂场景。 ### 总结 `RecentsActivity` 在 Launcher3 中扮演着至关重要的角色,不仅负责展示最近使用的应用程序列表,还承担了高效的用户交互处理和美观的动画呈现。通过对 `ActivityManager` 接口的调用以及丰富的 UI 组件集成,使得整个最近任务模块既功能强大又易于扩展。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值