chrome31 shell启动流程---初始流程及启动主进程
来源:互联网 发布:手机淘宝如何追评 编辑:程序博客网 时间:2024/05/16 23:40
先给一张基本流程图。
1.1. CommandLine初始化
CommindeLine init
从/data/local/tmp/content-shell-command-line中取出command buffer
设置command buffer到commandline中的scommand中
1.2. DeviceUtils
addDeviceSpecificUserAgetnSwitch(this)
判定是平板还是手机,然后根据判定在command中添加那种Ui类型。
1.3. 加载一些库以及注册Jni
LibraryLoader
1) loadAlreadtLocked()
a) system.loadLibrary(StringsLibary: NativeLibraries.libraries)
实际就是加载了”WebViewChromium”。
2) initializeAlreadyLocked(initcommdLine)
initcommdLine其实就是将之前commandline存储的mArgs内容转换过来。
a) nativeLibraryLoaded(initcommdLine):Library_loader_hooks.cc
i. InitNativeCommandLineFromJavaArray(initcommdLine):command_line.cc
AppendJavaStringArrayToCommandLine(initcommdLine);
CommandLine::ForCurrentProcess()->AppendArguments(initcommdLine);
ii. InitLogging
iii. RegisterJni
l Net::anroid::registerJni
l Ui::anroid::registerJni
l Ui::gl::anroid::registerJni
l Ui::shell::anroid::registerJni
l Content::android::registerChildJni
l Content::android::registerCommonJni
l Content::android::registerBrowserJni
l Content::android::registerAppJni
l meia::anroid::registerJni
b) commandline::enableNativeProxy
sCommnadLine.set(new NativeCommandline)
c) Jni_OnLoad
RegisterLibraryLoaderEntryHook
RegisterShellJni
Content::Compositor::Initialize()
Content::SetContentMainDelegate(newcontent::ShellMainDelegate())
1.4. 创建ShellManager.
New ShellManager
1). nativeInit(this): shell_manager: Init(enve class obj);
2). New mContentViewRenderView, 创建ContentViewRenderView
a. nativeInit: new content_view_render.cc
b. CreateSurfaceView
c. New SurfaceHolder.CallBack()
1.5. 创建WindowAndroid
WindowAndroid,包含了Context和Activity的指针,以及Intent信息。在后续的shell,shellManager都会用到。
1.6. 启动Browser进程
BrowserStartupController::startBrowserProcessAsync
启动Browser进程。
1) tryPrepareToStartBrowserProcess
启动之前,做好准备工作。
a. prepareToStartBrowserProcess(maxRenders)
i. ResouceExtractor::startExtractingResources萃取数据包中的资源
ii. ResouceExtractor::waitForCompletion
iii. nativeSetCommandLineFlags()
iv. ContentMain::initApplicationContext(appcontext);
v. Content_main.cc:base::android::initApplicationContext
2) ContentStart()
启动Content。
a. ContentMain::start()->nativeStart
b. Start() in content_main.cc
c. G_content_runner.reset(contentManRunner::Create();
d. ContentMainRunnerImpl::initialize()//初始化工作
i. ShellMainDelegate::BasicStartupComplete
ii. 在Command::ForCurrentProcess中添加参数。
iii. Content_Client.cc:SetContentClient(empty_content_client)
iv. ContentClientInitializer::Set(process_type,delegate_)
当没有process_type: Client->browser =ShellMainDelegate::CreateContentBrowserClient(); 为ContentClient创建一个ShellContentBrowserClient;
当process_type == “renderer”: Client->renderer_ =ShellMainDelegate::CreateContentRendereClient(); 为ContentClient创建一个ShellContentRendererClient;
v. RegisterPathProvider()
vi. RegisterContentSchemes
vii. Base::i18n::InitializeICU
viii. InitializeStatsTable(command_line)
ix. ShellMainDelegate::PreSandboxStartup():
InitializeResourceBundle(), 调用base::Path_service::get(base::DIR_ANDROID_APP_DATA,*)获取到Pak_dir, 然后将pak_dir加上paks/content_shell.pak,同过ResourceBundle::InitSharedInstancheWithPakFile();进入到ResourceBundle::LoadTestResources,然后通过DataPack将文件隐射到内存中。为什么调用的是LoadTestResources。
x. Webkit_glue::setUserAgent 如果command_line包含userAgent)
xi. ShellMainDelegate::SandboxInitialized(process_type),啥也没做
e. ContentMainRunnerImpl::Run
进入RunNamedProcessTypeMain(process_type,main_function_params, delegate); 生成一系列的MainFunction,但只有name == process_type类型的运行了。比如Process_type == “renderer那么做如下处理:
i. ShellMainDelegate::RunProcess(process_type,main_function_params)
也就是不管是那种类型的mianfunc运行都是需要运行这个。在ShellMainDelegate::RunProcess中创建browser_runner_,如上图,然后进入shell_browser_main.cc中的ShellBrowserMain(parameters,browser_runner_)。(Browser_main_runner.cc)
进入BrowserMainRunnerImpl::Initialze(parameters):
Ø 创建main_loop为BrowserMainLoop,将BrowserMainLoop的静态变量g_current_browser_main_loop设置为这个值.
Ø BrwserMainLoop::init, 通过ShellContentBrowserClient CreatBrowserMainParts。
Ø BrwserMainLoop::EarlyInitialization, 调用parts_-> PreEarlyInitialization,为networkChangeNotifer创建并设置factory。接着调用RenderProcessHost::setMaxRendererProcessCount(process_limit) 根据Commandline中的renderer-process-limit设置Renderer进程的最大数。最后调用Parts_->PostEarlyInitialization(),啥也没干
Ø BrwserMainLoop::InitializeToolkit
Ø BrwserMainLoop::MainMessageLoopStart()//Browser_main_runner.cc
n 调用parts_->preMainMessageLoopStart(), 进入shell::initialize(),从而进入PlatformInitialize();
n 创建main_message_loop为TYPE_UI的MessageLoop,构造这个MessageLoop时,将Message_loop::Current()设置为this,及lazy_tl_prt.Pointer()->set(this),然后为MessageLoop创建incoming_task_queue_,Message_loop_proxy, 设置message_pump
n InitializeMainThread(),创main_message_loop名字设置为CrBrowserMain,创建Main_thread为BrowserThreadImpl(BrowserThread::UI,main_message_loop)。创建BrowserThreadImpl时,记录当前线程的message_loop,而BrowserThread::UI,是作为BrowserthreadImpl的Id身份。
接下来在一个BrowserThreadGlobals的全局变量g_globals上记录一个信息对[identifier__][this]
然后构造一系列的成员变量。
n Parts_->postMainMessageLoopStart()。调用Base::MessageLoopForUi::Current->start(),其实这是一静态函数,MessageLoopForUi的静态函数Current,从Message::Current取来Loop。然后判定这个MessageLoop的类型是不是TYPE_UI,如果是就返回loop。进入到了MessagePumpForUi::Start。后续的不详述了。
n BrowserMainLoop::CreateStartuptasks
创建一些task闭包:包括prechreatethreads,CreateThreads,BrowserThreatsStarted,PreMainMessageLoopRun。参看browser_main_loop.cc中CreateStartuptasks:
到此,contentMain::Run的所有操作就完成了。BrowserStartController调用Callback,进入到ContentShellActivity::finishInitialization()。
1.7. 启动Shell
ContentShellActivity::finishInitialization()
shellManager::launchShell进入到natvilaunchShell,进入Shell::CreateNewWindow()
1.7.1.WebContentsImpl::CreateWithOpener
1). New WebContentsImpl
创建RenderViewHostManager.
2). WebContentsImpl::Init()
初始化RenderViewHostManager。
同时创建WebContentsView,为WebContentsViewAndroid。
1.7.2. CreateShell
1). New Shell 创建Shell
2).Shell->PlatformCreateWindow(with,height) //shell_android.cc
通过jni调用进入到shellManager::CreateShell //ShellManager.java
i. 创建ShellView: //shell.java
ii. ShellView.setWindow(window)
iii. 设置ContentView. ShellView.setContentViewRenderView(**)
iv. addView(shellView, 将shellView添加在ShellManager上。其中ShellManager是FrameLayout, shellView是LineaLayout。
v. 通过ShellView获取对应的ContentView,(如果ContenView存在,则将ContentView设置到ContentViewRenderView上。并显示出来) 第一次时是没有Contentview的,还未创建呢。
3). Shell->webContents.reset(web_contents)。
4). WebContents->SetDelegate(shell),Shell作为了WebContents的Delegate
5).Shell->PlatformSetContents()
通过jni调用进入到shell::InitFromNavtiTabContents。//Shell.java
i. 创建ContentView;ContentView::NewInstance(context, webcontents,window);
ii. 请求焦点 requestFocus
iii. 将ContentView关联到ContentViewRenderView
CreateShell就此完成。
1.7.2.Shell->LoadURL(url)
进入到Shell::LoadURLForFrame(**)
1) . 设置Params,用于WebContents的加载参数;
2). WebContents->GetController().LoadURLWithsParams(params)
1.7.3. ContentView::SetContentViewClient()
给ActiveContentView设置Client, 这个Client是临时New出来的,同时为Client创建了ContentVideoViewClient)。
那么启动的整个流程就结束了。
- chrome31 shell启动流程---初始流程及启动主进程
- 启动进程流程
- linux进程启动流程
- Zygote进程启动流程
- SystemServer进程启动流程
- Android进程启动流程
- android进程启动流程
- Linux内核启动进程流程
- Android System进程启动流程
- Zygote进程的启动流程
- Android 应用进程启动流程
- Android 应用进程启动流程
- Android 应用进程启动流程
- Android 应用进程启动流程
- startService启动应用进程流程
- docker启动Container进程之启动流程
- Android系统开机启动流程及init进程浅析
- ubuntu启动流程及定制
- codeigniter(CI)在apache环境下的rewrite规则
- 如何解决mysql导入数据乱码问题
- 用NSInvocation來作為object performSelector的替代方案(这样就可以带多个参数)
- libev and libevent
- 密码算法
- chrome31 shell启动流程---初始流程及启动主进程
- 新员工
- git merage出问题,不能自动Merage
- Linux + MySQL的基本配置
- vim 新建文件后自动插入模板
- python
- 在windows7,windows8 64位操作下5种方法加载未签名的驱动程序
- MSSQL sysobjects 结构说明
- DSPARM资深软件工程