<Android Framework 之路>BootAnimation(1)
来源:互联网 发布:15个java小项目 文库 编辑:程序博客网 时间:2024/06/05 11:55
介绍
开机动画,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.cppLOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPESLOCAL_C_INCLUDES += external/tinyalsa/includeLOCAL_SHARED_LIBRARIES := \ libcutils \ liblog \ libandroidfw \ libutils \ libbinder \ libui \ libskia \ libEGL \ libGLESv1_CM \ libgui \ libtinyalsaLOCAL_MODULE:= bootanimationifdef TARGET_32_BIT_SURFACEFLINGERLOCAL_32_BIT_ONLY := trueendifinclude $(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)
- 【android】【Bootanimation】Bootanimation---综述
- android------bootAnimation
- <Android Framework 之路>Android5.1 Camera Framework(一)
- <Android Framework 之路>Android5.1 Camera Framework(二)
- <Android Framework 之路>Android5.1 Camera Framework(三)
- Android 修改开机动画(bootanimation)
- Android 修改开机动画(bootanimation)
- 【android】【Bootanimation】Bootanimation---启动和退出
- android添加动态logo之bootanimation.zip制作 --- 小V
- Android系统定制之bootanimation.zip的制作
- Android bootanimation 制作过程
- android bootanimation 学习总结
- Android bootanimation制作过程
- android bootanimation.zip
- Android bootanimation 制作过程
- Android bootanimation 制作过程
- 微软认知服务开发实践(5) - 视频检测
- 56:Spark中的Tungsten内存和CPU的优化使用
- JDK and Jre
- 六度空间 地下迷宫探索 哈利·波特的考试 旅游规划 畅通工程之最低成本建设问题
- 欢迎使用CSDN-markdown编辑器
- <Android Framework 之路>BootAnimation(1)
- Android学习之Activity与Service进行通信的三种方式
- android_蓝牙模块的开发
- 扩展欧几里得的学习(未完成
- java代码动态修改app图标
- Java中重写equals函数加判断自己定义的对象相不相等
- Oracle 大数据集成实施
- JS强制类型转换
- Python3.4中filter函数,map函数和reduce函数