<Android Framework 之路>BootAnimation(1)
介绍
开机动画,BootAnimation,就是Android手机开机郭晨各种以一个展示给用户的界面,实际是一个多个帧组成的动画,在界面上进行一帧一帧的播放,形成开机动画的效果。
本文针对Android5.1源码分析BootAnimation
源码分析
1. 文件产生
Android平台的开机动画由system/bin下的bootanimation文件完成,而这个文件产生于
frameworks/base/cmds/bootanimation/Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
bootanimation_main.cpp \
AudioPlayer.cpp \
BootAnimation.cpp
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
LOCAL_C_INCLUDES += external/tinyalsa/include
LOCAL_SHARED_LIBRARIES := \
libcutils \
liblog \
libandroidfw \
libutils \
libbinder \
libui \
libskia \
libEGL \
libGLESv1_CM \
libgui \
libtinyalsa
LOCAL_MODULE:= bootanimation
ifdef TARGET_32_BIT_SURFACEFLINGER
LOCAL_32_BIT_ONLY := true
endif
include $(BUILD_EXECUTABLE)
编译结果为bootanimation的bin文件,所以,在有足够权限的前提下,在adb shell下执行bootanimation也是可以看到对应的开机动画效果的。
2. 启动开机动画
开机动画是以bin文件的形式存在于手机系统中,开机过程中通过init.rc定义
system/core/rootdir/init.rc
service bootanim /system/bin/bootanimation
class core
user graphics
group graphics audio
disabled//定义了disable,在开机过程中不会自动的启动
oneshot
这里不会启动,那么在哪里启动? 由于开机动画对SurfaceFlinger有依赖,所以应该是在SurfaceFlinger启动之后再开始执行,看一下源码。
SurfaceFlinger的启动在init.rc文件中
service surfaceflinger /system/bin/surfaceflinger
class core
user system
group graphics drmrpc
onrestart restart zygote
与SurfaceFlinger相关的源码存在于
frameworks\native\services\surfaceflinger
入口
frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
#if defined(HAVE_PTHREADS)
#include <sys/resource.h>
#endif
#include <cutils/sched_policy.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include "SurfaceFlinger.h"
using namespace android;
int main(int, char**) {
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);
// start the thread pool
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
#if defined(HAVE_PTHREADS)
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
#endif
set_sched_policy(0, SP_FOREGROUND);
// initialize before clients can connect
flinger->init();//开机动画在这里执行,接着往下看
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
// run in this thread
flinger->run();
return 0;
}
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
....
// start boot animation
startBootAnim();
}
接着执行startBootAnim();
void SurfaceFlinger::startBootAnim() {
// start boot animation
property_set("service.bootanim.exit", "0");
property_set("ctl.start", "bootanim");
}
这里采用的是通过property_set中”ctl.start”的方式执行bootanim,这里是通过设置属性值的方式来启动的,属性值的设置采用的是C/S模式,socket连接,这里不详述,大致说下,这行代码会执行到
system/core/init/property_service.c
void handle_property_set_fd()
{
......
switch(msg.cmd) {
case PROP_MSG_SETPROP:
......
//这里很关键
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)) {
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 {
if (check_perms(msg.name, source_ctx)) {
property_set((char*) msg.name, (char*) msg.value);
} else {
ERROR("sys_prop: permission denied uid:%d name:%s\n",
cr.uid, msg.name);
}
// Note: bionic's property client code assumes that the
// property server will not close the socket until *AFTER*
// the property is written to memory.
close(s);
}
freecon(source_ctx);
break;
default:
close(s);
break;
}
}
接下来执行到
system/core/init/init.c
void handle_control_message(const char *msg, const char *arg)
{
if (!strcmp(msg,"start")) {
msg_start(arg);//就是这条路
} else if (!strcmp(msg,"stop")) {
msg_stop(arg);
} else if (!strcmp(msg,"restart")) {
msg_restart(arg);
} else {
ERROR("unknown control msg '%s'\n", msg);
}
}
接着往下执行->
static void msg_start(const char *name)
{
struct service *svc = NULL;
char *tmp = NULL;
char *args = NULL;
if (!strchr(name, ':'))
svc = service_find_by_name(name);
else {
tmp = strdup(name);
if (tmp) {
args = strchr(tmp, ':');
*args = '\0';
args++;
svc = service_find_by_name(tmp);
}
}
if (svc) {
service_start(svc, args);
} else {
ERROR("no such service '%s'\n", name);
}
if (tmp)
free(tmp);
}
这里找到“bootanim”然后执行service_start函数,这里就是启动bootanim的地方。
<Android Framework 之路>BootAnimation(1)的更多相关文章
- <Android Framework 之路>BootAnimation(2)
前言 上一篇主要讲解了BootAnimation是从何而来,如何启动,从开机,到SurfaceFlinger服务起来,然后到执行开机动画,如果要深入的看里面的代码,是需要花一定的时间的,我们旨在了解大 ...
- <Android Framework 之路> N版本 Framework Camera的一些改动
前言 Android N版本最近发布,Nougat是否好吃,不得而知,慢慢看下~ 感谢AndroidXref这个网站,给开发者提供了大量的便捷~以后学习Android就靠它了. N版本上Framewo ...
- <Android Framework 之路>Android5.1 Camera Framework(三)
上一次讲解了一下startPreview过程,主要是为了画出一条大致的从上到下的线条,今天我们看一下Camera在Framework的sendCommand和dataCallback,这部分属于衔接过 ...
- <Android Framework 之路>Android5.1 Camera Framework(一)
Android5.0 Camera Framework 简介 CameraService启动 CameraService是在MediaServer启动过程中进行的 main_mediaserver.c ...
- <Android Framework 之路>多线程
多线程编程 JAVA多线程方式 1. 继承Thread线程,实现run方法 2. 实现Runnable接口 JAVA单继承性,当我们想将一个已经继承了其他类的子类放到Thread中时,单继承的局限就体 ...
- <Android Framework 之路>Android5.1 MediaScanner
前言 MediaScanner是Android系统中针对媒体文件的扫描过程,将储存空间中的媒体文件通过扫描的方式遍历并存储在数据库中,然后通过MediaProvider提供接口使用,在Android多 ...
- <Android Framework 之路>Android5.1 Camera Framework(四)——框架总结
前言 从之前的几篇文件,可以基本弄清楚 Camera从APK,经过framework的衔接,与HAL层进行交互,最终通过驱动完成Camera的一些动作. Camera层次分析 APP层 Framewo ...
- <Android Framework 之路>Android5.1 Camera Framework(二)
上一次讲解了一下CameraService的启动过程,今天梳理一下Camera预览的过程 StartPreview过程 首先,我们还是从应用层的使用入手 Camera.java (packages\a ...
- Android Framework 简介
Android Framework 简介 简介 之前的研究太偏向应用层功能实现了,很多原理不了解没有详记,结果被很多公司技术人员鄙视了,为了减少自己的短板,重新复习了一遍C++.java.Androi ...
随机推荐
- centos的基本命令02
16:查看系统运行的进程 ps -ef 17:查看系统已开放的端口 netstat -tunlp 18:管道命令 ps -ef | grep tom # 查看系统中与tom相关的进程 19:grep过 ...
- [转] maven打包可运行的fat-jar的简单方法
[From] https://blog.csdn.net/tearsky253/article/details/75948721 问题 在使用“mvn package”命令编译application之 ...
- odoo 的一些orm 操作
1.基础文件及目录结构 在认识odoo ORM框架前,先介绍一下odoo中模块目录结构. data:存放模块预制数据 i18n:存放国际化文件 models:存放模型等py代码 securit ...
- 送给张思漫,李志媛和王颖的C语言经典例题
1.打印乘法口诀表 #include<stdio.h> int main() { int i, j; ; i <= ; i++){ ; j <= i; j++) { print ...
- 通过shell处理多行数据
### 源文件 cat > tmpb <<'EOF' dbname:db_a,start_time::: query_end_time:::,query_total_time:,da ...
- wordpress 后台页面无法显示绑定的台湾语言
问题:当前切换到的语言是English,然后在页面的列表中,分别显示的语言有中文和香港,没有出现台湾的图标,如上图所示 原因:在polylang插件的设置里面,可以看到台湾语言的 Language c ...
- 仔细说明CLOSE_WAIT状态的原因
CLOSE_WAIT状态!!! 服务器收到客户端FIN报文后 服务器端口回复了ack,没有回复FIN报文. 1 说明客户端后面不会再向服务器发送用户层的数据了, 2 客户端 没有回复FIN 报文嘛 ...
- 《JavaScript编程精解》读书笔记
第一章 JavaScript基础:值.变量.控制流程 JavaScript里有六种基本类型:number类型.string类型.boolean类型.object.function和undefined. ...
- Apache和Tomcat的整合过程(转载)
一 Apache与Tomcat比较联系 apache支持静态页,tomcat支持动态的,比如servlet等. 一般使用apache+tomcat的话,apache只是作为一个转发,对jsp的处理是由 ...
- Android开发环境搭建步骤-【Android】
本教程是android开发环境在windows下的安装配置,经本人测试完全正确无误.这个教程是史上最详细的android开发环境搭建教程. 工具/原料 Eclipse 3.7.0.Java Jdk6. ...