Android 7.0 SystemUI(3)--RecentsActivity

RecentsActivity 是最近任务管理界面,通过该activity用户可以对启动的应用进行简单的管理。其配置信息如下

frameworks/base/packages/SystemUI/AndroidManifest.xml

        <activity android:name=".recents.RecentsActivity"
                  android:label="@string/accessibility_desc_recent_apps"
                  android:exported="false"
                  android:launchMode="singleInstance"
                  android:excludeFromRecents="true"
                  android:stateNotNeeded="true"
                  android:resumeWhilePausing="true"
                  android:screenOrientation="behind"
                  android:resizeableActivity="true"
                  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
                  android:theme="@style/RecentsTheme.Wallpaper">
            <intent-filter>
                <action android:name="com.android.systemui.recents.TOGGLE_RECENTS" />
            </intent-filter>
        </activity>
可以看到其launchMode为"singleInstance"。 RecentsActivity 启动的入口在
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

    private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
        public void onClick(View v) {
            awakenDreams();
            toggleRecentApps();
        }
    };
关于 RecentsActivity ,这里主要讨论3个方面,task的获取、应用缩略图的获取、task移除。

getRecentTasks

在ams中,有一个mRecentTasks对象,该对象保存了近期启动的task任务信息,RecentsActivity实际上是要获取mRecentTasks对象

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 

  /**
     * List of intents that were used to start the most recent tasks.
     */
    final RecentTasks mRecentTasks;


在上面的入口中,toggleRecentApps()最终会调用到

frameworks/base/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java

    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int numLatestTasks, int userId,
            boolean includeFrontMostExcludedTask, ArraySet<Integer> quietProfileIds) {
        ...
        int minNumTasksToQuery = 10;
        int numTasksToQuery = Math.max(minNumTasksToQuery, numLatestTasks);
        int flags = ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS |
                ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK |
                ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS |
                ActivityManager.RECENT_IGNORE_UNAVAILABLE |
                ActivityManager.RECENT_INCLUDE_PROFILES;
        if (includeFrontMostExcludedTask) {
            flags |= ActivityManager.RECENT_WITH_EXCLUDED;
        }
        List<ActivityManager.RecentTaskInfo> tasks = null;
        try {
            tasks = mAm.getRecentTasksForUser(numTasksToQuery, flags, userId);
        } catch (Exception e) {
            Log.e(TAG, "Failed to get recent tasks", e);
        }

        ...
        return tasks.subList(0, Math.min(tasks.size(), numLatestTasks));
    }
这里设置了flag,不去获取HOME_STACK_ID、DOCKED_STACK_ID、PINNED_STACK_ID上的task,根据机器内存大小设置了最大的查询数

frameworks/base/core/java/android/app/ActivityManager.java 
static public int getMaxRecentTasksStatic() {
        if (gMaxRecentTasks < 0) {
            return gMaxRecentTasks = isLowRamDeviceStatic() ? 36 : 48;
        }
        return gMaxRecentTasks;
    }
然后调用ActivityManager的getRecentTasksForUser方法

frameworks/base/core/java/android/app/ActivityManager.java 
public List<RecentTaskInfo> getRecentTasksForUser(int maxNum, int flags, int userId)
            throws SecurityException {
        try {
            return ActivityManagerNative.getDefault().getRecentTasks(maxNum,
                    flags, userId).getList();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
通过binder通信最终会进入到ams

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 
   public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
            int userId) {
        final int callingUid = Binder.getCallingUid();
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
                false, ALLOW_FULL_ONLY, "getRecentTasks", null);

        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
        synchronized (this) {
            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
                    callingUid);
            final boolean detailed = checkCallingPermission(
                    android.Manifest.permission.GET_DETAILED_TASKS)
                    == PackageManager.PERMISSION_GRANTED;

            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
                return ParceledListSlice.emptyList();
            }
            mRecentTasks.loadUserRecentsLocked(userId);

            final int recentsCount = mRecentTasks.size();
            ArrayList<ActivityManager.RecentTaskInfo> res =
                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);

            final Set<Integer> includedUsers;
            if (includeProfiles) {
                includedUsers = mUserController.getProfileIds(userId);
            } else {
                includedUsers = new HashSet<>();
            }
            includedUsers.add(Integer.valueOf(userId));

            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
                TaskRecord tr = mRecentTasks.get(i);
                // Only add calling user or related users recent tasks
                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
                    continue;
                }

                if (tr.realActivitySuspended) {
                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
                    continue;
                }

                // Return the entry if desired by the caller.  We always return
                // the first entry, because callers always expect this to be the
                // foreground app.  We may filter others if the caller has
                // not supplied RECENT_WITH_EXCLUDED and there is some reason
                // we should exclude the entry.

                if (i == 0
                        || withExcluded
                        || (tr.intent == null)
                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                                == 0)) {
                    if (!allowed) {
                        // If the caller doesn't have the GET_TASKS permission, then only
                        // allow them to see a small subset of tasks -- their own and home.
                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
                            continue;
                        }
                    }
                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
                        if (tr.stack != null && tr.stack.isHomeStack()) {
                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
                                    "Skipping, home stack task: " + tr);
                            continue;
                        }
                    }
                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
                        final ActivityStack stack = tr.stack;
                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
                                    "Skipping, top task in docked stack: " + tr);
                            continue;
                        }
                    }
                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
                        if (tr.stack != null && tr.stack.isPinnedStack()) {
                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
                                    "Skipping, pinned stack task: " + tr);
                            continue;
                        }
                    }
                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
                        // Don't include auto remove tasks that are finished or finishing.
                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
                                "Skipping, auto-remove without activity: " + tr);
                        continue;
                    }
                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
                            && !tr.isAvailabl
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: vmware-esxi-7.0u1-16850804-depot.zip是VMware公司发布的ESXi 7.0的更新版本。ESXi是一种VMware公司开发的企业级虚拟化技术,它是一种基于内核的虚拟化技术,能够将一台物理服务器分成多个虚拟机,每个虚拟机可以运行不同的操作系统和应用程序,从而实现服务器资源的最大化利用和灵活性。 这个更新版本带来了许多新功能和修复了一些已知的问题。其中包括增加了新的安全功能,比如支持更多的密码算法和证书选项;增加了对NVMe设备的支持;针对CPU等关键组件修复了已知的漏洞;提升了对虚拟化网络和存储的性能和可靠性等等。这些新功能和修复可以让用户更快速、更有效地部署和管理虚拟机环境,提升整个企业的服务质量。 总之,vmware-esxi-7.0u1-16850804-depot.zip是VMware公司为了不断完善和升级其ESXi虚拟化技术而推出的最新版本,用户可以通过更新来获取最新的功能和修复。这也一直是VMware公司赖以生存的关键因素,持续提升产品质量和完整性,为企业用户提供更好的IT基础设施。 ### 回答2: vmware-esxi-7.0u1-16850804-depot.zip 是一个文件压缩包,其中包含了 VMware ESXi 7.0 Update 1 的软件安装包。VMware ESXi 是一款基于 Linux 的虚拟化操作系统,它可以直接安装在物理服务器上,并在该物理服务器上提供虚拟化主机的功能。通过使用 VMware ESXi,我们可以在物理服务器上创建多个虚拟机,同时在这些虚拟机中运行 Windows、Linux 或其他操作系统,从而最大限度地利用硬件资源和实现服务器的资源共享。 在 VMware ESXi 7.0 Update 1 中,加入了多项新功能和改进,包括对最新硬件平台的支持、对容器化的增强支持、更好的安全性能和简化的管理方法。此外,通过更新版本也可以修复一些已知的安全漏洞和软件缺陷。 要安装 VMware ESXi 7.0 Update 1,需要先将该压缩包下载到本地,并通过如 VMware vSphere Update Manager 等工具来完成安装。安装过程中需要按照要求配置相关参数,并在安装完成后进行相关设置和管理。 总之,vmware-esxi-7.0u1-16850804-depot.zip 是一个非常重要的软件安装包,对于需要使用 VMware ESXi 虚拟化技术的企业或个人用户来说,具有重要的意义和价值。 ### 回答3: vmware-esxi-7.0u1-16850804-depot.zip是一种VMware ESXi 7.0更新1的安装文件。VMware ESXi是一种虚拟化操作系统,可以在物理计算机上运行多个虚拟机,从而提高计算机资源的利用率。更新1是该操作系统的一个版本更新,其中包括了一些功能改进和安全修补程序,能够提高VMware ESXi的性能和安全性。 安装文件zip格式的压缩包,用户可以通过解压缩这个文件来安装VMware ESXi 7.0更新1。在安装过程中,用户可以选择自定义安装选项来配置操作系统的设置,包括网络设置、存储设置、主机名等等。 VMware ESXi被广泛应用于企业、公共机构、教育机构等各个领域,帮助用户实现计算资源的高效利用和灵活管理。更新1版本的发布,说明VMware一直致力于不断完善和改进该操作系统,以满足用户的需求和提高产品的质量和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值