对此知之甚少,Google很少做广告,但是Android操作系统已经内置了一个主题框架已有好几年了。 它被称为运行时资源覆盖框架,简称RRO,它大大减少了为手机创建自定义主题所需的工作。
使用RRO,您可以快速创建主题,这些主题可以改变Android设备上安装的几乎每个应用程序的外观。 由于Android的系统用户界面组件(包括导航栏,状态栏,通知托盘和快速设置托盘)本身属于应用程序,因此您也可以更改其外观。 最好的部分是,您不必编写任何Java代码。
你问有什么要害? 好吧,该框架只能由特权应用程序使用。 更具体地说,是由安装在只有root用户或正在创建自定义ROM的用户才能访问的位置的应用程序。
在此快速提示中,我将向您展示如何使用框架创建一个简单的主题来更改快速设置托盘的外观。
先决条件
为了能够跟进,您需要满足以下条件:
- 运行Android棉花糖或更高版本的Android模拟器
- 最新版本的Android SDK
RRO真正做什么?
尽管Android应用程序的业务逻辑是用Java或Kotlin编写的,但其用户界面主要是使用XML文件创建的。 编写良好的Android应用程序将具有单独的XML资源,这些资源定义其布局,颜色,字符串和属性。 顾名思义,RRO框架使您可以使用自己的自定义XML资源覆盖这些XML资源。 但是,它不仅限于XML资源。 它还允许您更改应用程序的可绘制对象和字体。
使用RRO框架的应用程序通常不包含任何Java代码。 它仅由XML文件以及必要时的字体和图像组成。 但是,像所有Android应用一样,它必须是有效且经过签名的APK。
1.创建一个新项目
我们不需要Android Studio创建使用RRO框架的项目。 现在,您只需要一个新的项目目录和一个AndroidManifest.xml文件。 您可以使用文件浏览器或终端随意创建它们。
mkdir MyOverlays && cd MyOverlays
touch AndroidManifest.xml
清单文件必须包含您的应用程序的程序包名称,以及您要为其创建覆盖的应用程序的程序包名称。 因为我们今天要更改快速设置托盘的外观,所以必须使用com.android.systemui
作为目标程序包名称。
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="https://schemas.android.com/apk/res/android"
package="com.tutsplus.myoverlays">
<overlay android:targetPackage="com.android.systemui"
android:priority="1"/>
</manifest>
至此,我们准备开始快速设置托盘以及Android系统UI的任何其他组件的主题设置。
2.创建一个主题
要覆盖目标应用程序的资源,您的应用程序必须具有相同名称的资源。 例如,如果要更改目标应用程序的颜色,你通常必须覆盖其colors.xml文件用自己的colors.xml文件。
为了简化您的工作,RRO框架不希望覆盖层很全面,并且不能处理原始资源中存在的所有细节。 换句话说,您的叠加层只需要包含您要更改的那些细节。
为了使情况更清楚,假设我们要将快速设置托盘的背景颜色从默认的蓝灰色更改为深橙色。 颜色的值在系统UI应用程序的res / values / colors.xml文件中指定。 如果您对它的内容感到好奇,可以查看官方Android Git存储库中的文件 。
要更改颜色,现在必须在项目中创建一个res / values / colors.xml文件。
mkdir -p res/values
touch res/values/colors.xml
在colors.xml文件中,要更改任务栏的背景颜色,我们必须将目标颜色设置为system_primary_color
。 因此,将以下XML添加到文件中:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="system_primary_color">#FFBF360C</color>
<!-- deep orange 900 -->
</resources>
值得注意的是,上述XML与使用Android Studio创建普通应用程序时使用的XML并无不同。
我们的简单主题已准备就绪! 如果需要,可以向文件添加更多的<color>
标记以更改系统UI的其他颜色。
3.生成一个APK
现在,我们将使用Android Asset Packaging Tool( aapt
为Android SDK的一部分,简称aapt
将我们的简单项目转换为可被Android平台使用的APK文件。
要生成APK,您只需将aapt
指向清单文件, res目录和目标平台的android.jar文件。 当然,您还必须指定要为APK文件指定的名称。
aapt package -M AndroidManifest.xml -S res/ \
-I ~/Android/Sdk/platforms/android-23/android.jar \
-F myoverlays.apk.u
在上面的命令中,您可以看到我已选择将APK文件命名为myoverlays.apk.u 。 这是因为我们的APK当前未签名且未对齐。
要对其进行签名,必须使用jarsigner
工具。 现在,我建议您使用默认的Android调试密钥库对其进行签名。
jarsigner -keystore ~/.android/debug.keystore \
myoverlays.apk.u androiddebugkey
最后,您必须使用zipalign
工具对齐并优化APK。 作为输入,该工具需要未对齐和对齐的APK的名称,以及指定对齐边界的数字。 截至2017年,该数字只能是4
。
zipalign 4 myoverlays.apk.u myoverlays.apk
4.安装APK
要安装使用RRO框架的APK,您只需将其放置在/ system / vendor / overlay目录中。 默认情况下,该目录属于只读文件系统,并且只有root用户可以访问。 如果您是自定义ROM开发人员,或者已经扎根了Android设备,则安装APK应该没有问题。
但是,在此快速提示中,我将向您展示如何在模拟器上安装APK。 这样,您可以测试覆盖层而不会危害您的手机。
首先使用emulator
命令行工具以可写文件系统模式启动emulator
。
emulator -avd Nexus_5X_API_23 -writable-system
现在,您可以使用adb
工具在模拟器上获得root特权(如果尚未拥有)。
adb root
接下来,再次使用adb
将/ system文件系统挂载为可写状态。
adb remount
/ system / vendor / overlay目录在模拟器上不存在。 您必须自己手动创建它。 最简单的方法是在模拟器上启动外壳。
adb shell
mkdir -p /system/vendor/overlay
exit
最后,使用adb
将APK推送到目录。
adb push myoverlays.apk /system/vendor/overlay
等待几秒钟,以便Android检测并安装APK,然后重新启动模拟器以使主题生效。
重新启动后,如果您下拉快速设置托盘,则应该能够看到正在运行的主题。

结论
在此快速提示中,您学习了如何使用运行时资源覆盖框架来创建Android主题。 尽管我们创建的主题非常简单,但是您可以应用今天获得的技能来创建更加复杂的主题。 例如,您可以覆盖strings.xml文件以更改应用程序显示的UI元素的标签。 同样,您可以覆盖dimens.xml文件以更改应用程序UI元素的大小。
有关RRO框架的文档非常少。 尽管如此,通过研究Android平台的源代码,您可以学到很多东西。