一种基于Android的系统风格深度定制方法
2022-01-17张宏宽舒信阳胡权楼勇亮周伯涛
张宏宽,舒信阳,胡权,楼勇亮,周伯涛
(数源科技股份有限公司,浙江 杭州 310012)
0 引言
随着公交智能化的发展,信息屏在公共出行中得到广泛应用,它可以实现车辆行驶路线显示与站点动态提示、公共文明建设信息的精准投放以及突发事件的提示警告,为乘客提供出行引导,也提升了城市精神文明的建设。
目前行业中常见的公交信息屏,显示风格比较单一,对客户容易造成视觉审美疲劳,有时候也会出现界面内容与显示风格不搭配的情况,因此客户会经常要求设备厂家对显示风格进行更换,特别是产品在装车后,售后升级维护的工作量很大,造成很多人力和财力的浪费。也有厂商为客户提供了应用的多种主题供自主选择,但是都没有真正从底层去做这样一整套的整体风格自动切换,因而整体风格上的协调性和审美感也会大打折扣。本文给出了一种基于Android的系统风格深度定制方法,可以根据时令或其他触发条件自动去更新系统的整体风格,也可以由客户根据需求自主选择风格,对整个启动过程做风格切换。
1 系统总述
风格定制的系统框架如图1所示,在系统应用中设置定制化的自动触发条件,如监听到今天是春节,系统可以自动选取春节的喜庆风格,应用Apk的喜庆风格随即变化[1-2]。开机过程中三个阶段的显示动画会依次更新。这些自动触发条件可以是季节、节日,不同的触发条件对应不同的整体风格。也支持手动定制风格,比如要播报突发事件或是极端天气预警,在应用Apk的设置菜单中,选定相应风格,开机过程会自动更新[3-4]。
图1 风格定制示意图
自动定制和手动定制都是定制过程,自动定制是根据提前预设的触发条件自动选择风格,手动定制是根据喜好或特定信息选择风格,定制过程是一致的[5-6]。Android系统开始过程中包含三个阶段的显示动画,即Uboot Logo,Kernel Logo,Bootanimation,从底层开始的定制过程,主要是开机三个阶段的开机画面及动画风格的自动切换,具体包括Uboot层状态数据的存取;Kernel内核层、HAL&Framework系统层文件系统的读写;系统及应用接口的风格切换的配置;消息从底层到上层和由上层到底层的传递;基于脚本自动制作的图片和动画风格资源等。
2 风格切换过程概要
不管是自动定制还是手动定制,首先是风格的选取,系统获取风格设置消息,通知底层要切换到哪种风格;当底层知道了具体风格后,系统会把这个消息传递给上一层,完成相应风格的切换。Android系统风格切换过程如图2所示,分为两条主线,一是虚线所示[自上而下]的传输,二是粗线所示[自下而上]的更新[7]。
图2 风格定制软件流程图
2.1 [自上而下]的传输
切换状态的传输路径:系统与应用层>HAL&Framework层>Kernel层>Uboot层
如图2虚线部分所示,假定从当前[风格2]要切换到[风格1],需要把[风格1]的状态信息传到底层的Uboot层,因为系统开机的图片及动画是在开机过程中完成的,在Uboot层会更新第一张开机Logo;在HAL&Framework 层向下连接驱动层(kernel driver),向上给JNI或HAL提供接口(Android Native),通过文件系统传递消息;在Kernel层>Uboot层,Kernel层通过IOCtrl驱动接口获取上一层切换[风格1]消息值,用RTC寄存器赋值,把切换的消息保存起来,传递给Uboot层。
2.2 风格[自下而上]的更新
风格更新的路径:Uboot层>Kernel层>HAL&Framework层>系统与应用层。
如图2粗黑线所示,把需要切换相应风格的消息逐层上传,把对应风格相应层级的图片和动画风格展现出来,随后标记当前风格的图片和动画状态,提供给下一层级使用。点击“切换风格”,系统在完成[由上往下]的消息传递及配置后,自动重启,在重新启动的过程中,完成系统开机过程三个阶段的图片及动画,也包括系统风格的更新,步骤如下:
步骤1:在Uboot层获取RTC寄存器,得到需要切换的风格信息,通过Memory记录读取状态值,完成显示Uboot Logo;
步骤2:在Kernel层读取Memory特定位置记录的标记,得知上一层切换的是何种风格,完成显示Kernel Logo;
步骤3:在HAL&Framework层由文件系统的状态,得知上一层切换的图片或动画是何种风格,完成播放Bootanimation动画;
步骤4:在系统层由文件系统的状态,得知要更新的是何种风格,[标记]当前是何种风格的图画和动画 ,完成系统风格的更新。
3 分层说明
3.1 切换入口与消息的传递
3.1.1 系统与应用Apk设置
进入“设置”菜单中,系统通过[文件系统]获取当前是何种风格的图画和动画(假如当前风格为[风格2]),[标记]当前风格的状态,如要更新新的风格,如选中[风格1],点击“切换风格”,系统会自动更新相应[风格1]的图片和动画,以及系统风格;如果不更新则退出菜单,保持原来风格。
3.1.2 Hal&JNI状态
Hal层承上启下,通过Native和系统及应用相通,通过文件系统和kernel相通。
3.1.3 Kernel层设置
Kernel层和Hal或JNI是通过IOCtrl机制进行传递的,实质还是文件系统。Kernel接受到不同的信息后,会做不同的处理,此处就是写RTC的不同状态,告知下一层要切换状态的风格,通过RTC寄存器把状态保存起来供不同层级使用。
3.1.4 Uboot层状态的接受
在Kernel层中,我们要把传递的状态信息存在RTC寄存器中,利用RTC空余Bit位保存切换风格的状态。风格的状态信息从上层传递下来后,在Kernel层的时候给RTC寄存器赋值,把状态保存下来,寄存器和闪存的原理一样,只要不掉电或不被重写,寄存器的值是不变的,系统重启时RTC寄存器不会被复位,系统重启进入Uboot层时,去读这个RTC寄存器,从而获取到Kernel层想要传下来的是风格信息。
3.2 图片和动画及系统的风格更新
结合图2所示,系统重新启动后,在开机的过程中,系统需要完成三个阶段图片和动画的更新以及系统风格的更新。
3.2.1 Uboot Logo更新
系统在开机后完成基本配置就要显示Uboot Logo,显示风格的状态由RTC寄存器值传递过来,显示Logo的整个过程步骤如下:
A.通过读取RTC寄存器值,获取到将要更新的是何种风格的状态(Kernel层>Uboot层);
B.读取Memory固定区域中记录风格状态的数据,获取当前是何种风格状态;
C.对显示接口(show_logo(style1))进行统一,实现不同风格的装载;
D.如果与当前风格状态不一致,则把[风格1]的Uboot Logo装入显示接口(show_logo(style_1),并在Memory中记录更新后的状态,此时,我们把这种风格1的状态写Memory中保存起来。这些数据写在特定的Memory分区内,不受掉电、关机、恢复出厂设置的影响,所以能够保留确定的风格状态;
E.如果与当前风格状态一致,则把原有风格的Uboot Logo装入显示接口,进行状态值回填[9]。
3.2.2 Kernel Logo 更新
系统进入Kernel层,完成相应驱动加载后,会显示Kernel Logo,具体步骤如下:
A.通过读取Nandflash的特定数据,获取上一层Uboot的风格状态;
B.建立系统文件,更新文件系统状态,供HAL&Framework层、系统和应用层使用;
C.如果与当前风格状态不一致,则更新状态,把需要切换的[风格1]图片装入相应的文件接口;如果与当前风格一致,则状态不更新,把原来风格的图片装入到文件接口;
D.回填状态,通过显示接口进行logo显示;
3.2.3 Bootanimation动画更新
在Framework层,完成第三个阶段动画的播放,步骤如下:
步骤1 通过读取文件系统,Framwork层获取Kernel层需要更新的[风格1]状态后,判断是否与当前风格动画状态一致。
步骤2 如果不一致,先更新状态,把需要切换的[风格1]动画装入到播放接口;如果一致,则状态不更新,把原有风格的动画装入文件接口。
步骤3 回填状态,更新文件系统,通过播放接口播放动画。
3.3 正常开机
风格定制化后的正常开机,系统会显示当前标记的图片和动画,如图3粗黑线所标示。
图3 正常开机软件流程图
为了保证风格信息状态的确定性,在Memory(Nand Flash)空余区域 划分出专属区域记录切换的状态;在系统Uboot阶段去读取Memory中记录的当前风格状态,再去读RTC的状态,如果不做切换,会保持当前风格状态;在Kernel或Hal&Framework 风格更新之前,都会获取到原有的风格状态,根据获取的状态,做原有风格的更新。
3.4 多种风格的资源预设
系统预置多套风格供自由切换,因此需要准备多套风格的图片和动画等资源。同一风格的图片和动画分为Uboot Logo,Kernel Logo,Bootanimation动画,这些资源预置到内存后,需要按不同风格命名,如图4所示,对于开机过程三个阶段的图片或动画资源,切换成加载的目标格式等,可以借助Shell脚本自动完成。
图4 风格资源示意图
4 结论
本文针对公交信息屏的风格定制需求给出了一种基于Android的系统风格深度定制方法,并在多个公交信息屏项目上进行了应用,收到了良好的反馈。此方法适用于所有Android系统的信息显示设备,有非常友好的系统适配性。