Android14 Launcher3 定制主页丝滑使用Recents功能 (一)

aosp默认主页是Launcher3,其中Recents功能就属于Launcher3的功能。考虑这样一个问题,如果设备默认主页需要使用我们自己开发的主页,那么当向上滑动显示Recents最近任务列表的时候,是个什么效果:

当前窗口缩小并且慢慢透视,能看到桌面壁纸,紧接着同步显示缩略图,并且缩略图可以跟着手指移动,当最后放手的时候,显示出RecentsActivity,那么这几个步骤显示下来,会感觉眼花缭乱。

那么我们怎么优化呢? 当向上滑动的时候直接在当前窗口展示缩略图,最后放手的时候显示出RecentsActivity,一气呵成。

那么我们首先要考虑个问题:

Recents功能该怎么使用呢?那么接下来我们就先针对这个问题进行分析

思路:考虑将Launcher3中的Recents功能移植到我们自己的主页

一、一种粗暴的想法

将Launcher3的Recents设计到的内容打包成aar包,我们自己的主页直接去依赖这个aar包,那么就不需要过多考虑Launcher3中Recents的实现方式,因为实现方式大多都在aar包中,我们只考虑把Recents给展示出来。

那么直接动手操作

先看看Launcher3的代码结构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Recents功能核心业务都在quickstep中,但是还是离不开一些外部的公共类以及外部父类,比如:Recents的页面是

./packages/apps/Launcher3/quickstep/src/com/android/quickstep/RecentsActivity.java

public final class RecentsActivity extends StatefulActivity<RecentsState> {
    ......
}

但是其父类是StatefulActivity,位置如下:

./packages/apps/Launcher3/src/com/android/launcher3/statemanager/StatefulActivity.java

看到其实父类路径并不在quickstep模块路径下,所以我们不能仅仅把quickstep打包成aar,需要将所有的相关代码都打包进去,那么我们就需要从最外层打包。

看Launcher3的编译选项

./packages/apps/Launcher3/Android.bp

// Build rule for Quickstep app.
android_app {
    name: "MtkLauncher3QuickStep",

    static_libs: ["MtkLauncher3QuickStepLib"],
    optimize: {
        enabled: false,
    },

    platform_apis: true,
    min_sdk_version: "current",
    target_sdk_version: "current",

    privileged: true,
    system_ext_specific: true,
    overrides: [
        "Home",
        "MtkLauncher2",
        "MtkLauncher3",
        "Launcher3QuickStep",
    ],
    required: ["privapp_whitelist_com.android.launcher3"],

    srcs: [
        ":Mtklauncher-quickstep-ext_tests",
        ":Mtklauncher-ext_tests",
    ],

    resource_dirs: ["quickstep/res"],

    additional_manifests: [
        "quickstep/AndroidManifest-launcher.xml",
        "AndroidManifest-common.xml",
    ],

    manifest: "quickstep/AndroidManifest.xml",
    jacoco: {
        include_filter: ["com.android.launcher3.*"],
    }

}

从这里可以看出,Launcher3编译出来的是Launcher3QuickStep.apk。那么我们从这层将apk直接编译成aar包,如下:

实现aar编译规则

./packages/apps/Launcher3/Android.bp

android_library {
    name: "MtkLauncher3QuickStepAAR",

    //继承原始依赖
    static_libs: ["MtkLauncher3QuickStepLib"],

    //移除测试依赖
    //srcs: [
    //    ":Mtklauncher-quickstep-ext_tests",
    //    ":Mtklauncher-ext_tests",
    //],

    //包含原始代码和资源
    resource_dirs: ["quickstep/res"],
    manifest: "quickstep/AndroidManifest.xml",
    additional_manifests: [
        "quickstep/AndroidManifest-launcher.xml",
        "AndroidManifest-common.xml",
    ],

    // 禁用优化以保留调试信息
    //optimize: {
    //    enabled: true,
    //    proguard_flags_files: ["proguard.flags"],
    //},
    optimize: {
        enabled: false,
    },

    //保持SDK版本配置
    platform_apis: true,
    min_sdk_version: "current",
    target_sdk_version: "current",

    //移除APK特有配置
    //jacoco: {
    //    include_filter: ["com.android.launcher3.*"],
    //}
}

我们编译出MtkLauncher3QuickStepAAR.aar

把我们编译出来的MtkLauncher3QuickStepAAR.aar放入我们自己的主页,发现…Game Over

  1. 一般做为定制的主页,会依赖第三方库,开源库等。那么此时大量的库版本冲突,代码冲突。要解决的话估计会直接让你崩溃
  2. 直接将Launcher3打包成aar,那么aar中包含了大量的android源码api,那么直接导致和官方SDK存在大量的冲突,解决起来也能让你直接崩溃。就是和下图中的这个东东严重冲突

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. Java版本冲突,源码中使用的java版本和我们自己的主页编译使用的java版本不一致,导致编译出来的class也会存在大量冲突
  2. 编译出来的aar大概25M,这也会无形中增加了主页的包大小
  3. 等等 等等,还会有一些形形色色的问题等着你解决
  4. 至于我们自己的主页和systemui通信方面的系统配置信息,先解决完上面的问题,再考虑这个事情吧。比如:
    ./frameworks/base/core/res/res/values/config.xml
    
    //config_recentsComponentName这个是配置涉及到systemui需要绑定哪个进程的TouchInteractionService
    //这个主要是绑定目标服务
    <!-- Component name for the activity that will be presenting the Recents UI, which will receive
         special permissions for API related to fetching and presenting recent tasks. The default
         configuration uses Launcehr3QuickStep as default launcher and points to the corresponding
         recents component. When using a different default launcher, change this appropriately or
         use the default systemui implementation: com.android.systemui/.recents.RecentsActivity -->
    <string name="config_recentsComponentName" translatable="false"
            >com.android.launcher3/com.android.quickstep.RecentsActivity</string>
    

那么这种方式显然行不通了

二、抽丝剥茧的想法

既然将Launcher3直接打包成aar的方法行不通,那么我们考虑将跨进程部分抽离出来,让我们自己的主页和systemui实现通信,将Recents功能涉及到的缩略图相关数据从systemui传递到我们自己的主页,我们自己的主页拿到数据后再去显示出来。

我们先看看Launcher3中是怎么获取Recents数据的?

./packages/apps/Launcher3/quickstep/src/com/android/quickstep/SystemUiProxy.java

private IRecentTasks mRecentTasks;

/**
 * Sets proxy state, including death linkage, various listeners, and other configuration objects
 */
@MainThread
public void setProxy(ISystemUiProxy proxy, IPip pip, IBubbles bubbles, ISplitScreen splitScreen,
        IOneHanded oneHanded, IShellTransitions shellTransitions,
        IStartingWindow startingWindow, IRecentTasks recentTasks,
        ISysuiUnlockAnimationController sysuiUnlockAnimationController,
        IBackAnimation backAnimation, IDesktopMode desktopMode,
        IUnfoldAnimation unfoldAnimation, IDragAndDrop dragAndDrop) {
    ......
    mRecentTasks = recentTasks;
    ......
}

public ArrayList<GroupedRecentTaskInfo> getRecentTasks(int numTasks, int userId) {
    if (mRecentTasks != null) {
        try {
            //start by zhuyidian for Recents Debug
            Log.i(TAG,"Recents Debug getRecentTasks: mRecentTasks.getRecentTasks numTasks="+numTasks+", userId="+userId,new Exception());
            //end by zhuyidian for Recents Debug
            //这里我们看到了获取数据的调用
            final GroupedRecentTaskInfo[] rawTasks = mRecentTasks.getRecentTasks(numTasks,
                    RECENT_IGNORE_UNAVAILABLE, userId);
            if (rawTasks == null) {
                //start by zhuyidian for Recents Debug
                Log.i(TAG,"Recents Debug getRecentTasks: rawTasks is null");
                //end by zhuyidian for Recents Debug
                return new ArrayList<>();
            }
            //start by zhuyidian for Recents Debug
            Log.i(TAG,"Recents Debug getRecentTasks: rawTasks size="+rawTasks.length);
            for(GroupedRecentTaskInfo info: rawTasks){
                Log.i(TAG,"Recents Debug getRecentTasks: info="+info);
            }
            //end by zhuyidian for Recents Debug
         
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一点IT+

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值