ContentShell启动过程全分析(一)

来源:互联网 发布:汉字 知乎 编辑:程序博客网 时间:2024/04/30 01:04


一、概述

ContentShell的启动过程比较复杂,涉及的类比较多,总是看了这忘了那,于是萌生了将看过的初始化过程记录一下的想法。本文从UI初始化,Browser进程初始化和Render进程初始化三个方面来浅析一下ContentShell的初始化过程。主要关注一些关键对象的构造。

本文基于chromium31,android版本。

二、UI的初始化

整个CotnentShell的启动从UI的启动开始,在android中即从Activity的onCreate函数开始。下面先给一个UI初始化过程的一个流程图:


                                                                                                                                       流程图1

首先就该流程图以及后面的流程图做一个说明:

1.      流程图中只列出了一个关键的步骤,而并不是所有步骤

2.      Jni流程之上的部分是java代码,之下的部分是C++代码,这个大家应该清楚

3.      有的流程有1,2字样。那并不是分支,而是先后调用顺序,1在先2在后。

就UI方面来说,ContentShellActivity即使一个Activity,而随后相继构造的ShellManager,CotnentViewRenderView,Surfaceview, Shell(都是指java类)都可以看成一个控件(实际上他们继承自adnroid控件,SurfaceView本身就是android控件)。

SurfaceView即是最后显示页面内容的控件。而CotnentViewRenderView则负责管理SurfaceView。ContentShellActivity虽然是一个Activity,但真正的界面却并没有在该类中,而是在Shell类里,各种控件都在Shell类里。而ShellManager毫无疑问对Shell进行管理。这几个控件按下图所示的方式来叠放。


通过流程图1可以看到,上述其他类的构造都很直接,除了Shell类。该类的构造经过了非常长的流程,而这个流程就是Browser进程初始化的一部分。

三、Browser进程初始化

从流程图1中可以看出,BrowserStartupController::startBrowserProcessAsyn这个函数的字面意思就是 异步启动browser进程。

1.      ContentMainRunner类

这里关键说一下ContentMainRunner类,该类控制content的初始化,运行和销毁。不单是Browser进程,包括Render进程也有该类控制。Content_main.cc文件中的函数只是提供一个调用该类的接口。

在初始化过程中该类有一个关键的函数RunNamedProcessTypeMain。该类负责对不同的进程进行初始化,对于browser,render,gpu等进程调用不同的函数。所以上述流程图1中,RunNamedProcessTypeMain函数在调用RunProcess之前,实际上会先对进程进行初始化。如下:


                        流程图 2

由流程图2可以看出,所谓的进程初始化实际上就是创建并初始化相应的MessageLoop,这样主线程就建立起了消息循环的机制,可以接收并处理消息。关于消息循环机制可以参看我的早期文章。

2. CotnentView,ContentViewCore的初始化

Contentview和ContentViewCore是java端最重要的两个类,他们将content的大多数功能封装其中,对上层提供了接口,类似于android的webview。

它们的建立从流程图1的Shell::CreateShell开始。


3. RenderViewHost,RenderProcessHost等的初始化

这几个类的重要性就不再赘述了,它们的初始化从Shell::CreateNewWindow开始。


注意此时有的类只是构造了,还并没有调用init函数来进行一些设置,比如RenderProcessHost类。

这里说一个题外话,可以看到上述很多与UI无关的类都是通过Shell::CreateNewWindow这个流程来创建的。可以很自然的想到,如果新开标签页的话是不是可以直接通过该函数来实现。在chromium31上还没有求证,留待日后。

4. IPC相关类的初始化


这个流程相对于之前的初始化流程发生的稍微晚一些,从RenderProcessHostImpl::Init之后的流程只会发生一次,但是CreateRenderView可以有多次。关于进程间通信的内容可以参看早先的文章

5. 创建子进程


子进程实际上是作为一个service启动的,子进程的创建就是android中启动一个service的流程。注意,上述channel初始化的时候会建立一对socket套接字,属于子进程的那个套接字怎样给子进程呢?就是通过android建立service的时候传递的该参数。具体的可以参见android创建service的方法,我对此了解不多,就不再献丑了。

另外可以看到SandboxedProcessSercice类共有10个,它们都直接继承子CiledProcessService,这些就代表了子进程,也就是说最多可以同时有10个子进程。