chromium的源码非常大,选择合适的点入手能省不少力气。在

win7下编译chromium中我曾提到学习chromium源码的一个小工程test_shell,代码目录在src/webkit/tools/test_shell下,

打开src/webkit下的webkit.sln工程,在webkit下就能看到test_shell。test_shell是一个测试程序,代码和流程都很简单,

这篇笔记主要理清test_shell中的主流程和逻辑,为后面学习webkit打好基础,同时,我们也研究一下google的桌面程序都有哪些特点。

 
    打开test_shell_main.cc文件,找到main函数逐行分析。(windows环境)
    
    base::debug::EnableInProcessStackDumping();
    这句使程序生成crash dump,并将标准输出attach到控制台。具体参考SetUnhandledExceptionFilter API函数。
    base::EnableTerminationOnHeapCorruption();
    当堆越界或出错时终止进程,winxp sp3以上版本才支持。具体参考HeapSetInformation API函数。
 
    base::AtExitManager at_exit_manager;
    AtExitManager目的是执行类似atexit的动作,它采用后进先出的栈结构运行注册一系列的任务,当对象析构时会执行任务列表,最常用的是执行base::Singleton类型对象的销毁动作,可以看到Singleton的实现中如果有kRegisterAtExit属性,则自动将OnExit函数作为任务添加到AtExitManager中,这样,我们不但能在程序结束时指定Singleton对象的销毁顺序,还能定义更多动作来让AtExitManager帮助管理执行。
 
    TestShellPlatformDelegate::PreflightArgs(&argc, &argv);
    根据注释这一句使程序有机会提前根据OS处理一些命令行,并过滤掉一些特有命令。不深究。
 
    CommandLine::Init(argc, argv);
    const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
    这两句建立一个命令行解析对象,将命令行解释为一个命令列表。后续很多处理都根据parsed_command_line对象的解释结果,配置不同的功能和支持。关于后续不同配置的执行,不再一一详述。
 
    TestShellPlatformDelegate platform(parsed_command_line);
    为跨平台做的一些逻辑的代理,比如后续的platform.CheckLayoutTestSystemDependencies(),platform.SuppressErrorReporting(),platform.InitializeGUI()和platform.SelectUnifiedTheme()等调用,会检查、收集系统默认字体、字号、主题风格等UI相关的信息,并完成窗口注册等工作。多数为方便测试用,不深究。
 
    MessageLoopForUI main_message_loop;
    这行代码看似简单,却包含了chromium中线程和消息循环机制的精髓。test_shell工程中只是用来初始化一些状态,并未真正用到。简单来说,MessageLoop是为不同平台线程事件处理做的封装,MessageLoopForUI面向UI线程,对于windows来说,它是对Win32窗口的消息队列和循环机制做的封装。关于MessageLoop后续会有专门一篇来研究它。
 
    后面的数行代码全都是根据平台环境和命令行确定程序细节功能点,比如v8错误是否abort、窗口风格、加速渲染、url默认加载次数、http cache模式、html5支持等,先略过。
 
    TestShellWebKitInit test_shell_webkit_init(layout_test_mode);
    初始化webkit,配置webkit的各种参数。先略过。
 
    icu_util::Initialize();
    初始化icu,icu是一个为C/C++和Java语言提供Unicode和国际化支持的库,参考ICU - International Components for Unicode。chromium将它做为第三方库来支持Unicode。
 
    net::NetModule::SetResourceProvider(TestShell::ResourceProvider);
    为network模块设置资源句柄。由于浏览器对本地资源的访问是有限制的,chromium通过NetModule来管理network对本地资源的访问。以后再详细研究。
 
    platform.InitializeGUI();
 
    还记得前面提到的platform对象吗,这句为GUI初始化环境。对于windows来说,内部调用InitCommonControlsEx初始化标准控件风格,并完成窗口类注册,终于找到熟悉的代码了,呵呵。
 
    TestShell::InitializeTestShell(layout_test_mode, allow_external_pages);
    初始化test_shell程序。看代码主要初始化了ole、window list、resource等,同时根据command line设置crash dump,这里用到了google的crash开源处理框架breakpad,之前关于程序崩溃处理的博文中有介绍。
 
    GURL starting_url;
 
    GURL是对url的封装类,test_shell启动时会加载该url,其值在我这里为:“file:///D:/chromium/home/src_tarball/tarball/chromium/src/webkit/data/test_shell/index.htm”。
 
    std::string stats_filename = kStatsFilePrefix +
      base::Uint64ToString(base::RandUint64() & 0xFFFFFFFFL);
    RemoveSharedMemoryFile(stats_filename);
    base::StatsTable *table = new base::StatsTable(stats_filename,
      kStatsFileThreads,
      kStatsFileCounters);
    base::StatsTable::set_current(table);
    设置用于统计的stats table。stats table生成一个共享内存的随机名来保证不同实例的唯一性,内部通过一个hash表对刚兴趣的项进行计数。
 
    下面这几行代码就是窗口创建和运行的代码了:
 
    TestShell* shell;
    if (TestShell::CreateNewWindow(starting_url, &shell)) {
      shell->Show(WebKit::WebNavigationPolicyNewWindow);
 
      if (parsed_command_line.HasSwitch(test_shell::kDumpStatsTable))
        shell->DumpStatsTableOnExit();
 
      webkit_glue::SetJavaScriptFlags(TestShell::GetJSFlagsForLoad(0));
      MessageLoop::current()->Run();
    }
 
    TestShell类是对test_shell app的封装,前面已经调用过很多TestShell的静态函数了,
 
比如一系列的config设置、TestShell::InitLogging、TestShell::InitializeTestShell等。通过调用TestShell::CreateNewWindow函数,shell变量被实例化,
 
实际上内部是通过调用Initialize()函数完成,在windows下主要是创建主窗口m_mainWnd以及初始化主界面,包括“Back”、“Forward”、“Reload”、“Stop”四个按钮和URL编辑框,之后创建一个webview窗口并load url显示内容。
    MessageLoop::current()->Run();一句封装了主消息循环,内部通过base::RunLoop的run函数完成,
 
最终将调用到MessagePumpForUI::DoRunLoop中,DoRunLoop基本就是对消息循环的封装。
 
    当收到WM_QUIT消息时,消息循环结束,Run函数返回。经过几个函数的清理工作后,main函数结束。
 
    以上就是整个test_shell的主流程,看上去代码逻辑还是非常清晰的。真正的chromium逻辑比test_shell肯定要复杂,但大致类似。
 
可以看到chromium的代码面向对象的封装做的非常好,比如AtExitManager对退出逻辑的封装、MessageLoop对消息循环以及跨平台的包装等。另
 
外可以看到对command line的封装和处理占了很多语句,还有config、log、crash、statistic等的支持,这些是所有application都需要的部分,值得研究和学习。
 
    从对主流程的学习可以看到,涉及webkit的代码并不多,主要由TestShellWebKitInit和webkit_glue两个封装完成。另外比较重要的部分就是MessageLoop、跨平台以及UI和控件系统了,这几点将是我们后面研究的重点。

chromium ④的更多相关文章

  1. QT5利用chromium内核与HTML页面交互

    在QT5.4之前,做QT开发浏览器只能选择QWebkit,但是有过使用的都会发现,这个webkit不是出奇的慢,简直是慢的令人发指,Release模式下还行,debug下你就无语了,但是webkit毕 ...

  2. Google之Chromium浏览器源码学习——base公共通用库(一)

    Google的优秀C++开源项目繁多,其中的Chromium浏览器项目可以说是很具有代表性的,此外还包括其第三开发开源库或是自己的优秀开源库,可以根据需要抽取自己感兴趣的部分.在研究.学习该项目前的时 ...

  3. 如何在windows上编译Chromium (CEF3) 并加入MP3支持(二)

    时隔一年,再次编译cef3,独一无二的目的仍为加入mp3支持.新版本的编译环境和注意事项都已经发生了变化,于是再记录一下. 一.编译版本 cef版本号格式为X.YYYY.A.gHHHHHHH X为主版 ...

  4. 如何在Windows上从源码编译Chromium (CEF3) 加入mp3支持

    一.什么是CEF CEF即Chromium Embeded Framework,由谷歌的开源浏览器项目Chromium扩展而来,可方便地嵌入其它程序中以得到浏览器功能. CEF包括CEF1和CEF3两 ...

  5. 构建基于Chromium的应用程序

    chromium是google chrome浏览器所采用的内核,最开始由苹果的webkit发展而出,由于webkit在发展上存在分歧,而google希望在开发上有更大的自由度,2013年google决 ...

  6. ubuntu中chromium无法播放flash,安装flash

    ubuntu14.0.4中系统自带的chromium无法播放flash,后来查了下,得知chromium已经不支持adobe flash了,用户可使用pepper flash替代.安装pepper f ...

  7. windows下编译chromium浏览器的15个流程整理

    编译chromium 系统为windows, 国内在windows上编译chromium的资料比较少, 我这篇文章只能作为参考, 记录我遇到的一些问题,因为chromium团队也会修改了代码,或者编译 ...

  8. Google之Chromium浏览器源码学习——base公共通用库(二)

    上次提到Chromium浏览器中base公共通用库中的内存分配器allocator,其中用到了三方库tcmalloc.jemalloc:对于这两个内存分配器,个人建议,对于内存,最好是自己维护内存池: ...

  9. 浏览器-10 Chromium 移动版

    移动版 chromium 的iOS版和Android是为两个流行的移动操作系统设计的, UI方面进行了 较大的重新设计; 两者从外观上看颇为相似,但是其内部的渲染引擎的差别非常的大,原因在于iOS对应 ...

  10. 浏览器-09 javascript引擎和Chromium网络栈

    语言的运行 C/C++语言 使用编译器直接将它们编译成本地代码(机器指令),这是由开发人员在代码编写完成之后实施; 用户只是使用这些编译好的本地代码,这些本地代码被系统的加载器加载执行,由操作系统调度 ...

随机推荐

  1. 02 爬虫数据解析之re,xpath,beautifulsoup

    一.正则匹配 简单用法演示: 字符: print(re.findall(".","abccc31223dn哈哈")) ### . 匹配除了换行符以外的任意字符, ...

  2. win10更新后,可以远程桌面ping也没问题,但是无法访问共享文件夹的解决方法

    计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters 1.在键盘输入WIN+R键, ...

  3. c# 线程的生命周期

    对于线程而言有两种类型:前台线程,后台线程.前台与后台线程性质相同,但终止条件不同. 后台线程:在运行过程中如果宿主进程结束,线程将直接终止执行:在强制终止时,线程即终止执行不论线程代码是否执行完毕. ...

  4. 前端页面兼容ie8解决方法

    一.通用兼容文件的引用: 1.HTML5标签兼容方案:html5shiv.js GitHub地址:https://github.com/aFarkas/html5shiv/ IE8不支持HTML5的新 ...

  5. 三、存储过程(Stored Procedure)与游标(Cursor)

    一.存储过程 一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数,来执行它. 在大型数据库中,存储过程和触发器具有重要的作用.无论是存储过程还是触发器,都 ...

  6. ssm的web项目,浏览器使用get方法传递中文参数时,出现乱码

    ssm的web项目,浏览器使用get链接传递的为中文参数时,出现乱码 做搜索功能时,搜索手机,那么浏览器传递的参数为中文参数“手机”,但传递的默认编码格式为iso-8859-1,所以传到后台时,是乱码 ...

  7. JAVA8的LocalDateTime使用心得和工具类

    今天做不成的事,明天也不会做好. 同学们,JAVA8出了这么久,不知道你们有没有用过它的LocalDateTime类型,还是依然用Date类型呢?其实,LocalDateTime类型给我们提供了很多便 ...

  8. 逆袭之旅DAY15.东软实训.Oracle.约束、序列、视图、索引、用户管理、角色

    2018-07-11  08:26:00 有某个学生运动会比赛信息的数据库,保存了如下的表: 运动员sporter表:(运动员编号sporterid,运动员姓名name,运动员性别sex,所属系dep ...

  9. javascript void函数

    <a href="javascript:doTest2();void(0);">here</a> 但这儿的void(0)究竟是何含义呢? Javascrip ...

  10. python文件管理

    文件没有修改操作,修改的方式为打开文件--读取文件--内存中编辑文件--将内容写入文件 打开文件方式 with open('a.txt','w') as f: #操作系统自动关闭文件 f.write( ...