android+动画打包命令,Android 开机动画客制化
Android开机动画总共有三个过程。第一个开机动画是在Kenel启动时显示的,第二个开机动画是在init进程启动时显示的,这两个都是静态图片。第三个动画是在系统服务启动过程中显示的,他是一个动态图片,也是我们关注比较多的动画。
关于动画的播放,主要涉及frame buffer的知识,可以参考老罗的分析http://blog.csdn.net/luoshengyang/article/details/7691321/,从底层的角度,理清了Android的开机动画播放过程。
现在主要关注与开机动画相关的几个类、文件。
一、Kenel动画
Kenel logo是开机显示的第一个动画,用于显示Android内核正在启动过程中。播放的图片位于 vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo ,系统读取目录下的文件夹里面的logo图片(fwvga_kernel.bmp)显示到手机上的 。那么问题来了,系统默认读的是哪个文件夹? 如何客制化开机Kenel logo?我一修改这个文件夹不是所有的其他国家的logo都要变?
@1.1 系统默认使用哪个文件夹?
其实系统是有一套机制控制Kenel logo的,这也是客制化开机动画的基础,该目录下,有一个mk文件—rules.mk,他会决定当前系统使用哪一套开机kenel logo。
LOCAL_DIR := $(GET_LOCAL_DIR)
BOOT_LOGO_DIR := $(LOCAL_DIR)
#fix no boot_logo config
#LOCAL_CFLAGS += -DBOOT_LOGO=wvga
ifeq ($(strip $(BOOT_LOGO)),)
BOOT_LOGO = fwvga
endif
ifeq ($(strip $(MTK_LK_CAMERA_SUPPORT)), yes)
BOOT_LOGO = fhd
endif
$(info BOOT_LOGO = $(BOOT_LOGO))
$(info lk/logo/dir=$(LOCAL_DIR),builddir=$(BUILDDIR))
由上段代码可以看出来,在BOOT_LOGO没有赋值的情况下,默认使用fwvga文件夹下的Kenel logo。
@1.2 如何客制化开机Kenel logo?
看到这里,我们可以发现,如果要客制化开机Kenel logo图片,可以在rules.mk里面添加相关判断,以达到目的。以海外版本为例,我需要在发货海外的版本中,客制化kenel logo,就需要
1、在rules.mk中添加一下代码
#added by guohongcheng for kenel logo start
ifeq ($(strip $(KENEL_LOGO_PROC)), yes)
BOOT_LOGO = hd720
Endif
#added by guohongcheng for kenel logo end
这样当系统属性KENEL_LOGO_PROC是yes的时候,BOOT_LOGO会加载hd720下面的图片,
2、在ProjectConfig.mk中设置KENEL_LOGO_PROC值
而KENEL_LOGO_PROC这个属性值是在项目的ProjectConfig.mk设置的,添加一下语句
#added by guohongcheng for kenel logo start
KENEL_LOGO_PROC=yes
#added by guohongcheng for kenel logo end
3、配置完成过后我们只需在自己的自拟定文件夹hd720 中,( vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo 中将logo替换即可。
注意:
(1) 替换时所有图片的命名(不只是2张静态logo,其他的图片也需要拷贝到自拟定目录下进行改名)必须和默认文件夹保持一致 例如 xxxxxxxx_kernel.bmp 和 xxxxxxxx_uboot.bm
(2) 一般情况下要改61处文件名 这里给大家提供一个批量修改文件名的命令,防止人为造成的编译find -type f | grep cmcc| xargs rename ‘s/cmcc_lte_hd720/tl_lte_hd720_Italian/’参数为筛选选条件 第二个参数为需要替换的部分 第三个参数为替换成的部分
二、init 动画
@2.1 第二个开机动画的播放过程
第二个开机动画是在init进程开启时显示的图片,也就是在开启一系列系统进程的过程中显示。 init进程的入口函数main实现在文件system/core/init/init.cpp中,最终会调用console_init_action方法,代码如下:
static int console_init_action(const std::vector<:string>& args)
{
std::string console = property_get("ro.boot.console");
if (!console.empty()) {
console_name = "/dev/" + console;
}
int fd = open(console_name.c_str(), O_RDWR | O_CLOEXEC);
if (fd >= 0)
have_console = 1;
#ifdef MTK_INIT
else
ERROR("console_init: can't open %s\n", console_name.c_str());
#endif
close(fd);
fd = open("/dev/tty0", O_WRONLY | O_CLOEXEC);
if (fd >= 0) {
const char *msg;
msg = "\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n" // console is 40 cols x 30 lines
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
" A N D R O I D ";
write(fd, msg, strlen(msg));
close(fd);
}
显示第二个开机画面是通过调用函数load_565rle_image来实现的。在调用函数load_565rle_image的时候,指定的开机画面文件为INIT_IMAGE_FILE。INIT_IMAGE_FILE是一个宏,定义在system/core/init/init.h文件中,如下所示:
#define INIT_IMAGE_FILE "/initlogo.rle" , 即第二个开机画面的内容是由文件/initlogo.rle来指定的。如果文件/initlogo.rle不存在,或者在显示它的过程中出现异常,那么函数load_565rle_image的返回值就会等于-1,这时候函数console_init_action就以文本的方式来显示第二个开机画面,即向编号为0的控制台(/dev/tty0)输出“ANDROID”这7个字符。
@ 2.2 init 动画客制化
init logo的客制化与kenel logo的客制化相同,他对应logo文件夹下的fwvga_uboot.bmp。
三、第三个开机动画
制作开关机动画
3.1 开机动画的位置
system/media/bootanimation.zip,要修改开机动画就是修改bootanimation这个压缩文件。如果不存在该压缩包,使用原生自带的资源,其路径在system/framework/framework-res.apk/assets/images(android-logo-mask.png,android-logo-shine.png),但是比较难看,比较常见的就是“android”。所以要定制自己的开关机动画一般都是在system/media/目录下放置bootanimation.zip和shutanimation.zip.这里以开机动画为例,关机动画和开机动画其原理一样。
3.2 bootanimation.zip文件结构
bootanimation里面主要包含一个desc.txt以及N个文件夹。而文件夹里面放着的就是开机动画的图片资源。decs.txt的作用就是指导系统如何去执行开机动画。
desc.txt编写规范,例如开机动画需要用到2个文件夹,分别是folder1和folder2,开机的时候,先把folder1里面的图片都播放一遍,然后再循环播放folder2里面的文件,直到进入系统,decs.txt文档的内容如下:
320 480 12
p 1 0 folder1
p 0 0 folder2
320 480是代表屏幕的分辨率,12表示12帧每秒,简单地说12代表一秒钟播放12张图片;
p 1 0 part1:p就是play。1是播放一次,0是无限次。0代表阶段间隔帧数为0。folder1就是说,这条指令是针对folder1这个文件夹的;
p 0 0 part2:第一个0这里是代表循环播放,第二个0和上面第二条指令一样。folder2就是第二个文件夹。
总结规则如下:
第一条指令:[屏幕的分辨率] [播放频率]
第二条指令:[p] [播放次数] [间隔帧数] [文件夹]
第N条指令: 同上
3.3 压缩包
把需要用到的folder文件夹跟decs.txt打包成zip格式,必须是zip,不能是rar,且打包的时压缩方式选择“存储”模式。然后改名成为bootanimation.zip,最后将制作好的zip包push到/system/media目录下。
注意:bootanimation不能太大,一般最好不要超过3M。
@3.1 bootanimation的启动过程
第三个开机画面是由应用程序bootanimation来负责显示的。应用程序bootanimation在启动脚本system/core/rootdir/init.rc中被配置成了一个服务,如下所示:
service bootanim /system/bin/bootanimation
class core
user graphics
group graphics audio cw_access
disabled
oneshot
应用程序bootanimation的用户和用户组名称分别被设置为graphics。注意, 用来启动应用程序bootanimation的服务是disable的,即init进程在启动的时候,不会主动将应用程序bootanimation启动起来。当SurfaceFlinger服务启动的时候,它会通过修改系统属性ctl.start的值来通知init进程启动应用程序bootanimation,以便可以显示第三个开机画面,而当System进程将系统中的关键服务都启动起来之后,ActivityManagerService服务就会通知SurfaceFlinger服务来修改系统属性ctl.stop的值,以便可以通知init进程停止执行应用程序bootanimation,即停止显示第三个开机画面。接下来我们就分别分析第三个开机画面的显示过程和停止过程。
Zygote进程在启动的过程中,会将System进程启动起来,System进程在启动的过程中,会调用SurfaceFlinger类的静态成员函数instantiate来启动SurfaceFlinger服务。Sytem进程在启动SurfaceFlinger服务的过程中,首先会创建一个SurfaceFlinger实例,然后再将这个实例注册到Service Manager中去。在注册的过程,前面创建的SurfaceFlinger实例会被一个sp指针引用。从前面Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析一文可以知道,当一个对象第一次被智能指针引用的时候,这个对象的成员函数onFirstRef就会被调用。由于SurfaceFlinger重写了父类RefBase的成员函数onFirstRef,因此,在注册SurfaceFlinger服务的过程中,将会调用SurfaceFlinger类的成员函数onFirstRef。在调用的过程,就会创建一个线程来启动第三个开机画面。
SurfaceFlinger是在framework/native/services/surfaceflinger/Main_surfaceflinger.cpp 被启动的,首先会执行init方法,然后自行run方法,代码如下:
// initialize before clients can connect
flinger->init();
// publish surface flinger
sp sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
// publish GpuService
sp gpuservice = new GpuService();
sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
// run surface flinger in this thread
flinger->run();
在framework/native/services/surfaceflinger/SurfaceFlinger.cpp下,init()会方法的最后执行startBootAnim()
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
HAL_PIXEL_FORMAT_RGBA_8888);
......
// set initial conditions (e.g. unblank default device)
initializeDisplays();
// start boot animation
startBootAnim();
ALOGV("Done initializing");
}
startBootAnim()方法代码如下,它调用函数property_set来将系统属性“ctl.start”的值设置为“bootanim”,表示要将应用程序bootanimation启动起来,以便可以显示第三个开机画面。
void SurfaceFlinger::startBootAnim() {
#ifdef MTK_AOSP_ENHANCEMENT
// dynamic disable/enable boot animation
checkEnableBootAnim();
#else
// start boot animation
property_set("service.bootanim.exit", "0");
property_set("ctl.start", "bootanim");
#endif
}
当系统属性发生改变时,init进程就会接收到一个系统属性变化通知,这个通知最终是由在init进程中的函数handle_property_set_fd来处理的。 函数handle_property_set_fd实现在文件system/core/init/property_service.c中,如下所示:
static void handle_property_set_fd()
{
prop_msg msg;
int s;
int r;
struct ucred cr;
struct sockaddr_un addr;
socklen_t addr_size = sizeof(addr);
socklen_t cr_size = sizeof(cr);
char * source_ctx = NULL;
struct pollfd ufds[1];
const int timeout_ms = 2 * 1000; /* Default 2 sec timeout for caller to send property. */
int nr;
......
switch(msg.cmd) {
case PROP_MSG_SETPROP:
msg.name[PROP_NAME_MAX-1] = 0;
msg.value[PROP_VALUE_MAX-1] = 0;
if (!is_legal_property_name(msg.name, strlen(msg.name))) {
ERROR("sys_prop: illegal property name. Got: \"%s\"\n", msg.name);
close(s);
return;
}
getpeercon(s, &source_ctx);
if(memcmp(msg.name,"ctl.",4) == 0) {
// Keep the old close-socket-early behavior when handling
// ctl.* properties.
close(s);
if (check_control_mac_perms(msg.value, source_ctx, &cr)) {
#ifdef MTK_INIT
INFO("[PropSet]: pid:%u uid:%u gid:%u %s %s\n", cr.pid, cr.uid, cr.gid, msg.name, msg.value);
#endif
handle_control_message((char*) msg.name + 4, (char*) msg.value);
} else {
ERROR("sys_prop: Unable to %s service ctl [%s] uid:%d gid:%d pid:%d\n",
msg.name + 4, msg.value, cr.uid, cr.gid, cr.pid);
}
} else {
......
}
}
android+动画打包命令,Android 开机动画客制化相关推荐
- 完成谷歌Android设置向导,Android RRO机制的运用-----google开机向导客制化
上周五的时候领导分了一个任务,客户让在google开机向导里面增加一页,首先就想到了android的Overlay,然后网上搜了下,发下有很多人写了这方面的技术.而且写的都还不错,所以本篇只当记录作用 ...
- android开机动画视频教程,【Android开机动画制作教程】开机动画文件组成及其详解释疑!...
[开机动画位置] 安卓原版系统开机动画位置: system/media/bootanimation.zip或者data/local/bootanimation.zip 这两处的区别在于动画放在syst ...
- Android修改kernel logo和开机动画(android)
一.uboot 开机logo 1.安装图片工具 # sudo apt-get install netpbm2.生成logo脚本 //make-uboot-logo.sh #!/bin/sh #1.ub ...
- MTK Android 13平台开关机动画铃声客制化
MTK Android 13平台开关机动画铃声客制化 Android T和S的差异很大 主要是MtkShutdownThread.java和ShutdownThread.java差异 未完,待更新,填 ...
- Android 系统序列号从哪里来,以及客制化序列号
Android 系统序列号从哪里来,以及客制化序列号 系统获取序列号过程 客制化序列号 系统获取序列号过程 Android系统的SN号,实际是从"cmdline"里面的" ...
- Android 手机按键客制化详解
在Android 中会有以下5个按键(Back.Home.Menu.Power.Volume)与用户进行交互,Framework 层中实现按键功能,因此,从手机系统定制的角度,可以满足客户的客制化要求 ...
- Android 信号格客制化问题处理
[Android Q] 信号强度客制化代码位置: NR(5G) CellSignalStrengthNr.java updateLevel() LTE MtkSignalStrength.java u ...
- Android实现客制化系统apk在线签名
目录 一.基线代码签名key 二.如何生成自定义的签名pk8 .x509.pem 签名文件 三.如何使用签名key对apk进行重新签名 四.大厂商为了安全,使用自定义签名方式,而不采用原生的签名方式 ...
- Android 11.0 充电指示灯红绿显示简单客制化
客制化充电指示灯的文章在网上也有不少了,项目的需求是在百分百情况下量绿灯,其它情况下都是红灯,这里简单记录下在Android11,kernel-4.19版本下的修改内容,也给有相关需求的各位提供下思路 ...
最新文章
- c语言xml序列化,C# XML和实体类之间相互转换(序列化和反序列化)
- Android数据存储(三)——SQLite
- 关于写代码的几个看法
- 关于synchronize与lock的区别
- 计算机网络 | 网络层 :IP协议详解
- ArrayList和Vector的异同
- /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.17' not found 解决办法
- c form画直线_新手教程跟我一起画儿童裤子裁剪图
- 好的设计善于利用PSD模板,轻松搞定促销海报!
- Linux C编程Makefile编写初步-转
- [转]:vue-cli3.0配置详解
- 【数据库】sql2008卸载和默认实例的删除
- 博士申请 | 澳门大学张一博教授课题组招收计算机视觉方向全奖博士生
- 如何让win7像win10一样漂亮-win7美化
- AspNetPager 存储过程
- 好未来表格识别大赛 | 获奖名单新鲜出炉!
- U3D记腾讯面试经历
- 第十五周博客作业西北师范大学|李晓婷
- HTML5 table表格合并单元格和合并边框
- USB转串口驱动分析(一)
热门文章
- 虚拟服务器面板,主流的虚拟主机控制面板有哪些(一)
- 基于Python下Tkinter实现学生选课管理系统
- 带你一起学习C语言语法
- anaconda navigator启动时一直卡在 loading applications 页面(已解决)
- mht 转换 html java,使用java将网页保存为mht格式(2)
- android sdk 需要下载安装哪些
- 程序员基础能力系列(1)——vim快捷键总结
- opencv的java api_OpenCV Java开发教程
- 2018年c++达内从入门到精通全套教程
- ppt怎么转pdf?经验分享