Android q Launcher最近任务栏移植
一、介绍
自Android P起始,Google将最近的任务栏功能移植至Launcher应用程序模块中。因此,在Launcher应用升级至Android Q时,最主要的迁移任务仍是最近的任务栏功能。然而,在这一过程中需考虑最新版本对系统UI的支持情况。例如,在导航操作过程中涉及的各种滑动操作会被传递至最近的任务栏以触发其相关功能。此外,在Quickstep目录下会包含最新版本的任务栏模块代码(即latest taskbar module code)。该模块会依赖System UI相关的库文件,并在Android P版本内通过预装的方式将其整合进Quickstep libs目录下以便编译使用。通常情况下,默认使用Android Studio进行开发以简化编译与调试流程。但在 Android Q环境中相关编码可能会发生较大变化,并且不再像P版本那样提供预先打包好的共享库文件支持自定义构建需求。
二、方案选择
有两种移植方案:
将Android Q近期的任务栏导入Launcher,并将其以往的功能转移至现有代码库
二、在Android p最近任务栏代码上修改代码做适配
综合两种方案我选择了第一种有以下几个理由:
1.android q原生最经任务栏代码整套移植可以避免很多莫名其妙的问题
我们在最近的任务栏中取得了进步。主要在界面进行调整,并未对整体架构造成影响。这使得框架移植更加便捷,并且保持了原有功能的完整性。
3.google原生框架调整肯定有很多优化但我们无法看出来
4.若此次未全部迁移至完整版本,则后续版本迭代与Google代码间的差距可能逐渐扩大导致维护难度上升
三、移植步骤
1.打包sysui-shared.jar
2.移植quickstep目录代码全部重新移植到Launcher
3.处理移植各种编译问题
4.编写make编译脚本实现android studio和make两种方式都能编译通过
5.顺利运行Android q最近任务栏保证原生功能正常使用
6.移植原有功能到最新最近任务栏
7.替换掉原生Launcher
1.替换sysui-shared.jar
移植过程中开始花了一些时间找sysui-shared.jar
原生Launcher引入sysui-shared.脚本方式
ifneq (,$(wildcard frameworks/base))
LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
LOCAL_PRIVATE_PLATFORM_APIS := true
else
LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI libLauncherProtos
LOCAL_SDK_VERSION := system_current
通过上述脚本查找得到out\target\common\obj\JAVA_LIBRARIES\SystemUISharedLib_intermediates目录中存在相关jar包
目前系统UI相关的任务栏及插件代码位于frameworks\b\packages\SystemUI\shared和frameworks\b\packages\SystemUI\plugin_core文件夹中;此前曾思考将这些代码转移至Quickstep目录进行操作, 但随后发现长期维护较为困难
取到上面jar包后替换原有的sysui-shared.jar包
Android Q的SysUI-shared.jar下载位置为:<>]
2.移植quickstep目录代码
将quickstep项目的整个代码库成功迁移至Launcher平台。尽管这一过程充满挑战(虽然过程充满挑战),但为了后续系统的稳定性和可维护性(为了后续系统的稳定性和可维护性),我仍咬牙坚持(仍咬牙坚持)。移载完成后,则面临如何解决编译器报错的问题(移载完成后,则面临如何解决编译器报错的问题)。首要任务是确保Android Studio能够正常构建APK文件(首要任务是确保Android Studio能够正常构建APK文件)。因为签名问题导致Android Studio编译出的APK无法直接安装(因为签名问题导致Android Studio编译出的APK无法直接安装),因此,在这种情况下(在此情况下),我们需要采用make命令进行编译,并等待系统层面进行签名处理。(在此过程中)。(可以提前系统签名方式替换掉android studio里面现有签名)。(在此过程中)。(在此过程中)
该过程对 Android P 的 make脚本进行编译时出现错误信息,并与原生 Launcher 进行了对比分析。进一步发现,在 include $(CLEAR_VARS) 之后增加了两个变量:LOCAL_USE_AAPT2 和 LOCAL_AAPT2_ONLY,并均赋值为 true。
3.运行apk保证原生最近任务栏功能可用
这一措施至关重要。因为如果不先确保原生最近任务栏的可用性,在持续进行自研功能的过程中可能会导致一系列难以解决的问题
1.桌面上拉起最近任务栏,kill进程等功能
2.第三方应用界面拉起最近任务栏
3.第三方laucnher拉起最近任务栏
4.切换不同导航栏方式验证以上几种情况
注意;各种横竖屏,切换动画和task内容显示等细节
4.移植最近任务栏自己的修改
在确保原有功能正常运行的基础上进行移植,在另一个系统中实现我们的功能。这个过程相对来说比较繁琐。为了便于后续调试和排查问题,在对比当前Android P的功能迁移的基础上建议采用分阶段的方式:每次完成一定数量的功能迁移后发布新版本,并通过对比新旧版本的代码来排除问题。在某些情况下,如果一次性修改过多代码可能会遇到困难;具体到问题时需要逐一排查哪些代码导致了问题。
5.make脚本编译写法
由于我只需配置带有最新功能的 Launcher ,因此简化了 make 文件,并使该方案便于大家参考。
LOCAL_PATH := $(call my-dir)
#
# Build rule for Launcher3 Go app with quickstep and Go-specific
# version of recents for Android Go devices.
#
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true
LOCAL_MODULE_TAGS := optional
#
# Build rule for Quickstep library.
#
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true
LOCAL_AAPT2_ONLY := true
LOCAL_MODULE_TAGS := optional
#这里是对一些jar和so等库文件引入
include $(CLEAR_VARS)
LOCAL_MODULE := gson3
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_SRC_FILES := libs/gson-2.8.0.jar
LOCAL_UNINSTALLABLE_MODULE := true
#LOCAL_SDK_VERSION := current
LOCAL_PRIVATE_PLATFORM_APIS:=true
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := libxypatch3
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES_32 := libs/armeabi/libxypatch.so
LOCAL_SRC_FILES_64 := libs/arm64-v8a/libxypatch.so
LOCAL_MULTILIB := both
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
include $(BUILD_PREBUILT)
#
# Build rule for plugin lib (needed to write a plugin).
#
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true
LOCAL_AAPT2_ONLY := true
LOCAL_MODULE_TAGS := optional
ifneq (,$(wildcard frameworks/base))
LOCAL_STATIC_JAVA_LIBRARIES:= PluginCoreLib
else
LOCAL_STATIC_JAVA_LIBRARIES:= libPluginCore
endif
LOCAL_SRC_FILES := \
$(call all-java-files-under, src_plugins)
LOCAL_SDK_VERSION := current
LOCAL_MIN_SDK_VERSION := 28
LOCAL_MODULE := LauncherPluginLib
include $(BUILD_STATIC_JAVA_LIBRARY)
#
# Build rule for Launcher3 dependencies lib.
#
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true
LOCAL_AAPT2_ONLY := true
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_ANDROID_LIBRARIES := \
android-support-compat \
android-support-media-compat \
android-support-core-utils \
android-support-core-ui \
android-support-fragment \
android-support-v7-recyclerview \
android-support-dynamic-animation \
android-support-design \
#iconloader_base
LOCAL_STATIC_JAVA_LIBRARIES := LauncherPluginLib
LOCAL_SRC_FILES := \
$(call all-proto-files-under, protos) \
$(call all-proto-files-under, proto_overrides) \
$(call all-java-files-under, src_build_config) \
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_PROTOC_OPTIMIZE_TYPE := nano
LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ --proto_path=$(LOCAL_PATH)/proto_overrides/
LOCAL_PROTO_JAVA_OUTPUT_PARAMS := enum_style=java
LOCAL_SDK_VERSION := current
LOCAL_MIN_SDK_VERSION := 21
LOCAL_MODULE := Launcher3CommonDepsLib
LOCAL_PRIVILEGED_MODULE := true
LOCAL_MANIFEST_FILE := AndroidManifest-common.xml
include $(BUILD_STATIC_JAVA_LIBRARY)
#
# Build rule for Quickstep library.
#
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true
LOCAL_AAPT2_ONLY := true
LOCAL_MODULE_TAGS := optional
#最近任务栏sysui_shared相关代码引用
ifneq (,$(wildcard frameworks/base))
LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
LOCAL_PRIVATE_PLATFORM_APIS := true
else
LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI libLauncherProtos
LOCAL_SDK_VERSION := system_current
LOCAL_MIN_SDK_VERSION := 26
endif
#静态库引入有些重复地方省略
LOCAL_STATIC_JAVA_LIBRARIES += mplus ... objenesis2.13 gson3
LOCAL_JNI_SHARED_LIBRARIES += libxypatch3
#模块名
LOCAL_MODULE := Launcher3QuickStepLib
LOCAL_PRIVILEGED_MODULE := true
LOCAL_STATIC_ANDROID_LIBRARIES := \
Launcher3CommonDepsLib
#编译代码路径
LOCAL_SRC_FILES := \
$(call all-java-files-under, src) \
$(call all-java-files-under, quickstep/src) \
$(call all-java-files-under, quickstep/recents_ui_overrides/src) \
$(call all-java-files-under, iconloaderlib/src) \
$(call all-java-files-under, iconloaderlib/src_full_lib) \
$(call all-java-files-under, src_flags) \
$(call all-java-files-under, src_ui_overrides)
#编译资源路径
LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/quickstep/res \
$(LOCAL_PATH)/iconloaderlib/res \
$(LOCAL_PATH)/quickstep/recents_ui_overrides/res
LOCAL_PROGUARD_ENABLED := disabled
#编译AndroidManifest.xml路径
LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
include $(BUILD_STATIC_JAVA_LIBRARY)
#
# Build rule for Quickstep app.
#
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3QuickStepLib
LOCAL_PROGUARD_ENABLED := disabled
ifneq (,$(wildcard frameworks/base))
LOCAL_PRIVATE_PLATFORM_APIS := true
else
LOCAL_SDK_VERSION := system_current
LOCAL_MIN_SDK_VERSION := 26
endif
#最终Launcher编译名
LOCAL_PACKAGE_NAME := Launcher3QuickStep
LOCAL_PRIVILEGED_MODULE := true
LOCAL_PRODUCT_MODULE := true
LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3
LOCAL_REQUIRED_MODULES := privapp_whitelist_com.android.launcher3
#签名方式
LOCAL_CERTIFICATE := platform
LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/quickstep/res \
$(LOCAL_PATH)/quickstep/recents_ui_overrides/res
LOCAL_FULL_LIBS_MANIFEST_FILES := \
$(LOCAL_PATH)/AndroidManifest.xml \
$(LOCAL_PATH)/AndroidManifest-common.xml
LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.*
include $(BUILD_PACKAGE)
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true
# ==================================================
include $(call all-makefiles-under,$(LOCAL_PATH))
6.Android studio 编译build.gradle脚本
基本上无需做过多改动,主要是因为最近任务栏中新增了一些新目录必须进行导入.
总结:
从Android P移植至Android Q Launcher耗时约10个工作日。其中涉及发现问题以及原有功能的迁移工作。每一次移植工作都是对系统架构的一次全面梳理与分析。整个过程要求有条不紊地制定工作流程与操作规范是十分必要的。如果东一榔头西一棒子地操作可能会导致各种问题难以解决而让人感到沮丧。通过总结经验教训有助于他人更好地把握整体框架从而提高工作效率
