本文共 3272 字,大约阅读时间需要 10 分钟。
函数handle_control_message实现在system/core/init/init.c中,如下所示: -
void handle_control_message(const char *msg, const char *arg) -
-
if (!strcmp(msg,"start")) { -
-
} else if (!strcmp(msg,"stop")) { -
-
-
ERROR("unknown control msg '%s'\n", msg); -
-
控制类型的系统属性的名称是以"ctl."开头,并且是以“start”或者“stop”结尾的,其中,“start”表示要启动某一个服务,而“stop”表示要停止某一个服务,它们是分别通过函数msg_start和msg_stop来实现的。由于当前发生变化的系统属性是以“start”来结尾的,因此,接下来就会调用函数msg_start来启动一个名称为“bootanim”的服务。 函数msg_start实现在文件system/core/init/init.c中,如下所示: -
static void msg_start(const char *name) -
-
-
-
-
-
-
svc = service_find_by_name(name); -
-
-
-
-
-
-
svc = service_find_by_name(tmp); -
-
-
-
service_start(svc, args); -
-
ERROR("no such service '%s'\n", name); -
-
-
-
参数name的值等于“bootanim”,它用来描述一个服务名称。这个函数首先调用函数service_find_by_name来找到名称等于“bootanim”的服务的信息,这些信息保存在一个service结构体svc中,接着再调用另外一个函数service_start来将对应的应用程序启动起来。 从前面的内容可以知道,名称等于“bootanim”的服务所对应的应用程序为/system/bin/bootanimation,这个应用程序实现在frameworks/base/cmds/bootanimation目录中,其中,应用程序入口函数main是实现在frameworks/base/cmds/bootanimation/bootanimation_main.cpp中的,如下所示: -
int main(int argc, char** argv) -
-
#if defined(HAVE_PTHREADS) -
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY); -
-
-
char value[PROPERTY_VALUE_MAX]; -
property_get("debug.sf.nobootanimation", value, "0"); -
int noBootAnimation = atoi(value); -
LOGI_IF(noBootAnimation, "boot animation disabled"); -
-
-
sp<ProcessState> proc(ProcessState::self()); -
ProcessState::self()->startThreadPool(); -
-
-
sp<BootAnimation> boot = new BootAnimation(); -
-
IPCThreadState::self()->joinThreadPool(); -
-
-
-
这个函数首先检查系统属性“debug.sf.nobootnimaition”的值是否不等于0。如果不等于的话,那么接下来就会启动一个Binder线程池,并且创建一个BootAnimation对象。这个BootAnimation对象就是用来显示第三个开机画面的。由于BootAnimation对象在显示第三个开机画面的过程中,需要与SurfaceFlinger服务通信,因此,应用程序bootanimation就需要启动一个Binder线程池。 BootAnimation类间接地继承了RefBase类,并且重写了RefBase类的成员函数onFirstRef,因此,当一个BootAnimation对象第一次被智能指针引用的时,这个BootAnimation对象的成员函数onFirstRef就会被调用。 BootAnimation类的成员函数onFirstRef实现在文件frameworks/base/cmds/bootanimation/BootAnimation.cpp中,如下所示: -
void BootAnimation::onFirstRef() { -
status_t err = mSession->linkToComposerDeath(this); -
LOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err)); -
-
run("BootAnimation", PRIORITY_DISPLAY); -
-
mSession是BootAnimation类的一个成员变量,它的类型为SurfaceComposerClient,是用来和SurfaceFlinger执行Binder进程间通信的,它是在BootAnimation类的构造函数中创建的,如下所示: -
BootAnimation::BootAnimation() : Thread(false) -
-
mSession = new SurfaceComposerClient(); -
SurfaceComposerClient类内部有一个实现了ISurfaceComposerClient接口的Binder代理对象mClient,这个Binder代理对象引用了SurfaceFlinger服务,SurfaceComposerClient类就是通过它来和SurfaceFlinger服务通信的。 回到BootAnimation类的成员函数onFirstRef中,由于BootAnimation类引用了SurfaceFlinger服务,因此,当SurfaceFlinger服务意外死亡时,BootAnimation类就需要得到通知,这是通过调用成员变量mSession的成员函数linkToComposerDeath来注册SurfaceFlinger服务的死亡接收通知来实现的。 BootAnimation类继承了Thread类,因此,当BootAnimation类的成员函数onFirstRef调用了父类Thread的成员函数run之后,系统就会创建一个线程,这个线程在第一次运行之前,会调用BootAnimation类的成员函数readyToRun来执行一些初始化工作,后面再调用BootAnimation类的成员函数htreadLoop来显示第三个开机画面。
本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/967042,如需转载请自行联系原作者