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

- Java版本冲突,源码中使用的java版本和我们自己的主页编译使用的java版本不一致,导致编译出来的class也会存在大量冲突
- 编译出来的aar大概25M,这也会无形中增加了主页的包大小
- 等等 等等,还会有一些形形色色的问题等着你解决
- 至于我们自己的主页和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


3460

被折叠的 条评论
为什么被折叠?



