<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 ...
随机推荐
- 【sql server】"已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行" 解决方案
#事故现场: 1.在手动修改某表中数据是,出现如下错误提示: 已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行 2.表结构及数据: #解决方法: 1.原因分析:提示被删除的行不是唯一行, ...
- CSS: Multiple Attribute Selector [name="value"][name2="value2"]
this.document.querySelectorAll('div[id*="dayselector"][class*="x-autocontainer-innerC ...
- stark - 1 ⇲一些理念
⒈.django项目启动时,自定义执行某个py文件. 在任意的app的apps.py中的Config类中定义ready方法,并调用autodiscover_modules from django.ap ...
- Windbg双机调试环境配置(Windows7/Windows XP+VirtualBox/VMware+WDK7600)
简介:Windbg双机调试内核.驱动 下载软件: 下载Windbg(GRMWDK_EN_7600_1.ISO) 下载VirtualBox 5.2/VMware 12 一.安装WDK,这里要提一点的是D ...
- 计算机网络透明网桥算法时间戳c++
要交CG的兄弟们别抄啊,撞上了严nan谁都不会放过的 好久没写博客了,这次是老师布置的作业,做出来一种,觉得写得很不好,第一种方法把情况都写死在代码里了. 上代码 #include<iostre ...
- SpringCloud---API网关服务---Spring Cloud Zuul
1.概述 1.1 微服务架构出现的问题 及 解决: 1.1.1 前言 每个微服务应用都提供对外的Restful API服务,它通过F5.Nginx等网络设备或工具软件实现对各个微服务的路由与负载 ...
- 《大数据日知录》读书笔记-ch11大规模批处理系统
MapReduce: 计算模型: 实例1:单词统计 实例2:链接反转 实例3:页面点击统计 系统架构: 在Map阶段还可以执行可选的Combiner操作,类似于Reduce,但是在Mapper sid ...
- javascrpit sort()数组对象中排序
/*ionic 调用 * @param attr 排序的属性 如number属性 * @param rev true表示升序排列,false降序排序 * */ commonSortMethod(att ...
- Vector bit-select and part-select addressing verilog片选写法
大端 m m[ a +: b ] == m[ (a+b-1) : a ] m[ a -: b ] == m[ a : (a-b+1) ] 小端 n n[ a +: b ] == n[ a : (a+b ...
- 我java学习时的模样(一)
学会敲键盘,能够实现盲打 程序员写代码,是通过键盘将程序输入到编辑器中,而码子的高效,能够让自己的思路更流畅一些.如果想从事IT工作,那面打字就必须得会,并且,如果还一个一个字母去找,上司就会认为是一 ...