google_chrome_源代码_分析.docx

上传人:小飞机 文档编号:1893934 上传时间:2022-12-24 格式:DOCX 页数:93 大小:1.02MB
返回 下载 相关 举报
google_chrome_源代码_分析.docx_第1页
第1页 / 共93页
google_chrome_源代码_分析.docx_第2页
第2页 / 共93页
google_chrome_源代码_分析.docx_第3页
第3页 / 共93页
google_chrome_源代码_分析.docx_第4页
第4页 / 共93页
google_chrome_源代码_分析.docx_第5页
第5页 / 共93页
点击查看更多>>
资源描述

《google_chrome_源代码_分析.docx》由会员分享,可在线阅读,更多相关《google_chrome_源代码_分析.docx(93页珍藏版)》请在三一办公上搜索。

1、*(本文从网上整理得到,源地址谷歌浏览器的源码分析(1)收藏随着网络技术的发展,越来越多应用都已经离不开网络,特别像人类大脑一样的知识库的搜索引擎,更加是离不开功能强大的云计算。不过,即便云计算非常强大,但它还不能直接地把结果呈现给用户,这样就需要一个客户端来呈现出来,这个客户端就是浏览器。现在越来越多人上网,他们每一次上网,都离不开浏览的使用,这已经是一个不可缺少的软件了。这里介绍和分析谷歌推出有创新的浏览器,它的速度比其它浏览器快很多,那么它是怎么实现的呢?又采用了什么样的技术能达到这样呢?又比如它的标签页是每一个进程进行显示的,这到底又是怎么样实现的呢?下面来通过分析它的源码,一一地解开

2、这种高新技术的使用,以及这种高效算法的奥秘。谷歌浏览器的英语名称为Chrome,它的意义是铬。铬是一种有光泽的、蓝灰色的坚硬金属元素。不失光泽,抗腐蚀,最早在铬铁矿中发现。用作催化剂,可加强钢合金的强度和生产不锈钢,可以做防腐镀层和玻璃制品中的颜料。原子序数24;原子量51.996;比重7.18;化合价2,3,6。谷歌起这个名称,可能是想让这个浏览器永远不失去光泽,永远那么吸引人。铬是无毒,化学性质很稳定,有延展性,含杂质时硬而脆。熔点1857C,沸点2672C,密度单晶为7.22克/厘米3,多晶为7.14克/厘米3;铬,原子序数24,原子量51.9961。铬的名称来自希腊文Chroma,意为

3、颜色。因为这种元素以多种不同颜色的化合物存在,故被称为“多彩的元素”。可用于制不锈钢,汽车零件,工具,磁带和录像带等。铬镀在金属上可以防锈,也叫可多米,坚固美观。红、绿宝石的色彩也来自于铬。作为现代科技中最重要的金属,以不同百分比熔合的铬镍钢千变万化,种类繁多,令人难以置信。谷歌的开发人员称,虽然网络的发展日新月异,但作为网络平台的浏览器,却没有跟上网络发展的步伐。谷歌倾心打造的免费浏览器就是希望能跟随着网络的发展而不断升级换代,完美的切合网络时代的潮流。据了解,谷歌员工每天使用的最多的应用程序就是浏览器,通过浏览器,查看新闻资讯,观看视频聊天,玩网络游戏。谷歌的员工说,如果能够开发出一种全新

4、的浏览器,才能够满足人们使用应用程序和网站管理员的要求。谷歌希望能够提供一种速度更快,稳定性更高,安全性更强的浏览器。因此Google Chrome诞生了!为了学习这个浏览器,需要通过网络把这份达到1G以上的代码下载下来,需要的时间就需要好几个小时,然后再把硬盘空间清空为10G左右大小,最后配置好VC 2005,就可以编译这个“可多米”了。在我的电脑上编译,共需要两个小时左右,才完全编译完成,最后生成下面的可多米,如下图:缺省编译出来的可多米是英语版本的,从关于对话框里就可以看到。下面是编译出来的目录图片,如下:上面是调试版本的输出文件,所以程序大小都比较大,没有经过优化的处理。整个程序的大小

5、,需要编译137个工程,共1G多的源码大小,这是一个非常旁大的一个工程。谷歌浏览器的源码分析(2)收藏这么大的工程,我从哪里开始呢?我认为从界面开始,这样才可以快速地深入研究。下面就可以先尝试修改一个chrome的关于对话框,上一次看到它是英语的,那么我就来把它改成中文的吧,这样有目标了。从chrome的工程里可以看到它是支持多种语言的,在Windows平台上支持多语言的标准做法,就是写多个语言的DLL。因此,chrome也不例外,从app工程集里,就可以看到如下图所示:上面显示了多种语言的动态连接库资源,其中zh-CN是简体中文的。接着打开资源文件的字符串编辑,如下图:把上面的字符串修改为

6、“关于 可多米”,然后把这个工程重新编译一下,就会生成下面的文件:然后运行自己编译的可多米,就会显示出修改的成果,如下图:可以看到关于对话框的标题,就变成我上面修改的了。这样学习它的修改,就是几分钟的事情,哈哈.这样就学习了可多米开发汉化的工作,这是本地化的重要做的一件事情,也学习到怎么样支持多语言的实现方式。那么它的关于对话框是从那里显示出来的呢?怎么样把字符串更新到上面的呢?下一次再告诉你。 谷歌浏览器的源码分析(3)收藏前面修改了chrome关于对话框,并且编译显示出来了,那么它是在那里调用显示的呢?现在就带你去了解它。由于它是界面显示,那么不用想,直接到界面的工程里查找它,也就是到目录

7、srcchromebrowserviews里查看到文件about_chrome_view.cc。这个文件里声明了一个类AboutChromeView,它就是主要负责初始化对话框、布局、显示字符串等等,比如显示“关于可乐米”的字符串,就是这样实现的,先调用函数:#001std:wstring AboutChromeView:GetWindowTitle() const return l10n_util:GetString(IDS_ABOUT_CHROME_TITLE);获取资源里的对话框标题,接着:在上面的断点里就是响应菜单,然后创建关于对话框,主要调用函数CreateChromeWindow来

8、创建窗口,把AboutChromeView窗口绑定到这个窗口类型里。由于可多米都是统一的窗口样式,那么它是通过创建一样的窗口类CustomFrameWindow来实现的。为了显示窗口的标题,是通过下面的函数关系调用:1Browser:ExecuteCommand浏览器执行菜单命令。2ChromeViews:Window:CreateChromeWindow创建窗口。3ChromeViews:CustomFrameWindow:Init初始化窗口。4ChromeViews:Window:Init初始化窗口标题。5AboutChromeView:GetWindowTitle从关于对话框获取标题。理

9、解上面的函数关系调用就知道怎么样显示标题了,因此也知道关于对话框所有内容是由类AboutChromeView来管理的,但窗口的样式是由CustomFrameWindow类来管理的。通过上面的分析,了解了关于对话框的标题显示过程,你想修改成什么样的内容,就要看你的需要了。下一次再仔细地分析有关于对话框怎么样组织其它信息,比如重要的升级功能。谷歌浏览器的源码分析(4)收藏关于对话框,主要实现了让用户查看当前软件的版本、软件信息和检查升级的功能。因此这个类主要继续ChromeViews:View类、ChromeViews:DialogDelegate和GoogleUpdateStatusListen

10、er。其中ChromeViews:View实现窗口的布局和显示问题,ChromeViews:DialogDelegate实现了事件响应,或者窗口某时是否可以显示按钮的问题,GoogleUpdateStatusListener是用来实现接收更新程序状态信息。这个类的声明如下:class AboutChromeView : public ChromeViews:View,public ChromeViews:DialogDelegate,public GoogleUpdateStatusListener public:explicit AboutChromeView(Profile* profil

11、e);virtual AboutChromeView();/ Initialize the controls on the dialog.void Init();/ Overridden from ChromeViews:View:virtual void GetPreferredSize(CSize *out);virtual void Layout();virtual void ViewHierarchyChanged(bool is_add,ChromeViews:View* parent,ChromeViews:View* child);/ Overridden from Chrome

12、Views:DialogDelegate:virtual int GetDialogButtons() const;virtual std:wstring GetDialogButtonLabel(DialogButton button) const;virtual bool IsDialogButtonEnabled(DialogButton button) const;virtual bool IsDialogButtonVisible(DialogButton button) const;virtual bool CanResize() const;virtual bool CanMax

13、imize() const;virtual bool IsAlwaysOnTop() const;virtual bool HasAlwaysOnTopMenu() const;virtual bool IsModal() const;virtual std:wstring GetWindowTitle() const;virtual bool Accept();virtual ChromeViews:View* GetContentsView();/ Overridden from GoogleUpdateStatusListener:virtual void OnReportResults

14、(GoogleUpdateUpgradeResult result,GoogleUpdateErrorCode error_code,const std:wstring& version);private:/ The visible state of the Check For Updates button.enum CheckButtonStatus CHECKBUTTON_HIDDEN = 0,CHECKBUTTON_DISABLED,CHECKBUTTON_ENABLED,;/ Update the UI to show the status of the upgrade.void Up

15、dateStatus(GoogleUpdateUpgradeResult result,GoogleUpdateErrorCode error_code);Profile* profile_;/ UI elements on the dialog.ChromeViews:ImageView* about_dlg_background_;ChromeViews:Label* about_title_label_;ChromeViews:TextField* version_label_;ChromeViews:TextField* main_text_label_;/ UI elements w

16、e add to the parent view.scoped_ptr throbber_;ChromeViews:ImageView success_indicator_;ChromeViews:ImageView update_available_indicator_;ChromeViews:ImageView timeout_indicator_;ChromeViews:Label update_label_;/ Keeps track of the visible state of the Check For Updates button.CheckButtonStatus check

17、_button_status_;/ The class that communicates with Google Update to find out if an update is/ available and asks it to start an upgrade.GoogleUpdate* google_updater_;/ Our current version.std:wstring current_version_;/ The version Google Update reports is available to us.std:wstring new_version_avai

18、lable_;DISALLOW_EVIL_CONSTRUCTORS(AboutChromeView);通过关于对话框的分析,可以理解到chrome浏览器窗口基本组成,以及窗口继承关系,还有事件的响应方式。前面三次分析,主要是入门的分析,也是了解这么一个大工程的一种手段。比如测试整个工程是否可以编译,是否可以修改代码等等。后面的分析会以浏览器输入HTTP连接开始,直到打开网页显示为一个主线,做一个基本的分析。谷歌浏览器的源码分析(5)收藏当用户打开浏览器之后,最希望输入的地方,是浏览器的连接框。目前谷歌浏览器把输入连接框与搜索引擎输入合并到一起,可以说完美的组合,让界面更加简洁,方便实用,并且它

19、自动完成的功能更加强劲,如下图所示:上面输入了www.c时,它就会自动地在后面添加智能选择的连接,并且可以GOOGLE里搜索输入的内容,又如下面:上面在输入框里输入我的名字,就会自动弹出查找的内容,或者可能搜索的连接。这些功能都比较完美的实现,这可以说是史无前例的输入创新,真正人性化的体现,那么它又是怎么样实现的呢?其主要功能是在文件srcchromebrowserautocompleteautocomplete_edit.cc里实现,具体的实现方式内容等下一次再去分析。谷歌浏览器的源码分析(6)收藏前面已经介绍了这么引人的输入自动完成功能,并且可以在输入超级连接框里直接通过GOOGLE搜索所

20、有的内容,这是比较大的创新,不但可以节省界面的占用面积,还很方便大家查询的需要,比如记不住的连接,根本不需要去记了,只要你记住需要的内容就行了。这样既不需要到什么门户网站去找连接,也不需要去记住众多的网站,这个功能是非常方便的。这个输入框的自动完成的功能,是比较智能化的。因为它会根据以往的输入自动完成,或者智能提示所需要的连接或者内容。下面就来先看这个类的定义:#001/ Provides the implementation of an edit control with a drop-down#002/ autocomplete box. The box itself is impleme

21、nted in autocomplete_popup.cc#003/ This file implements the edit box and management for the popup.#004/#005/ This implementation is currently appropriate for the URL bar, where the#006/ autocomplete dropdown is always displayed because there is always a#007/ default item. For web page autofill and o

22、ther applications, this is#008/ probably not appropriate. We may want to add a flag to determine which#009/ of these modes were in.#010class AutocompleteEdit#011: public CWindowImplAutocompleteEdit,#012CRichEditCtrl,#013CWinTraits ,#015public CRichEditCommands,#016public Menu:Delegate 类AutocompleteE

23、dit继承了类CWindowImpl、类CRichEditCommands、类Menu:Delegate。其中类CWindowImpl实现了Windows窗口,它是WTL里的窗口模板类,主要用来创建窗口界面类,并且使用类CRichEditCtrl作为基类,类CRichEditCtrl主要调用Windows里的编辑类。类CRichEditCommands实现RichEdit的命令功能。Menu:Delegate类是实现智能下拉式菜单的提示界面。因此,要学习开发chrome,需要先学习WTL的开发,它是一套基于模板的窗口框架。下一次再仔细地分析自动完成的实现过程。谷歌浏览器的源码分析(7)收藏当我

24、们键入字母或者文字开始时,那么类AutocompleteEdit就会从窗口消息里获取到相应的字母或者文字,然后根据输入的信息到本地或者网络上保存的信息库里查找相应的输入提示,这就是自动完成的实现。下面就来先分析输入的函数:#001void AutocompleteEdit:OnChar(TCHAR ch, UINT repeat_count, UINT flags) #002/ Dont let alt-enter beep.Not sure this is necessary, as the standard#003/ alt-enter will hit DiscardWMSysChar(

25、) and get thrown away, and#004/ ctrl-alt-enter doesnt seem to reach here for some reason?At least not on#005/ my system. still, this is harmless and maybe necessary in other locales.下面把alt-enter组合键消息过滤掉。#006if (ch = VK_RETURN & (flags & KF_ALTDOWN)#007return;#008#009/ Escape is processed in OnKeyDow

26、n.Dont let any WM_CHAR messages propagate#010/ as we dont want the RichEdit to do anything funky.下面把ESC键的消息过滤掉。#011if (ch = VK_ESCAPE & !(flags & KF_ALTDOWN)#012return;#013下面把TAB键的消息过滤掉。#014if (ch = VK_TAB) #015/ Dont add tabs to the input.#016return;#017#018这里处理其它有用的按键消息。#019HandleKeystroke(GetCurr

27、entMessage()-message, ch, repeat_count, flags);#020AutocompleteEdit:OnChar函数是WTL里的WM_CHAR消息处理,当用户键入字母时就会触发这个消息。这个函数先跳过几个不要处理的消息,最后调用函数HandleKeystroke来处理,如下:#001void AutocompleteEdit:HandleKeystroke(UINT message, TCHAR key,#002UINT repeat_count, UINT flags) 冻结RichEdit的更新。#003ScopedFreeze freeze(this,

28、 GetTextObjectModel();处理消息变化前的动作。#004OnBeforePossibleChange();处理消息#005DefWindowProc(message, key, MAKELPARAM(repeat_count, flags);处理消息变化后的动作。#006OnAfterPossibleChange();#007在这里为什么要进行窗口的消息冻结呢?又为什么需要进行消息处理和消息变化后处理呢?谷歌浏览器的源码分析(8)收藏上一次说到处理WM_CHAR消息,当用户每键入一个字符时,万能连接框就会去进行一次查找的过程,然后把智能提示信息显示出来。说到Autocompl

29、eteEdit:HandleKeystroke函数的操作,那么它为什么需要冻结这个函数的使用呢?现在就来分析这部份的内容。如下:ScopedFreeze freeze(this, GetTextObjectModel();在这行代码里,首先会调用函数GetTextObjectModel()来获取一个文档ITextDocument接口,然后再使用它的功能。这个函数的代码如下:#001ITextDocument* AutocompleteEdit:GetTextObjectModel() const 先判断这个接口是否获取到,如果已经获取到就不再去重复获取了。#002if (!text_objec

30、t_model_) #003/ This is lazily initialized, instead of being initialized in the#004/ constructor, in order to avoid hurting startup performance.这里使用了智能指针来获取IRichEditOle接口。#005CComPtr ole_interface;获取到的IRichEditOle接口绑定到智能指针里。#006ole_interface.Attach(GetOleInterface();下面通过=操作符获取ITextDocument接口,如果你深入去分

31、析这个赋值操作符,会看到它自动去调用IRichEditOle的接口IUnknown:QueryInterface来查询到ITextDocument接口,这个过程对于程序员来说是完全不用关心的,这就是使用mutable CComQIPtr text_object_model_定义的作用。#007text_object_model_ = ole_interface;#008#009return text_object_model_;#010通过上面的分析,可见使用CComQIPtr智能指针可以省了很多COM调用的操作,这真是模板类的强大功能的使用之处。当把ITextDocument接口获取回来之后

32、,对于RichEdit操作就可以轻松访问了,ScopedFreeze类生成一个局部对象,这个对象实现了对RichEdit自动冻结和解冻结的功能,这个过程是通过局部对象在栈里生命周期的特性应用。如下面的代码:#001AutocompleteEdit:ScopedFreeze:ScopedFreeze(AutocompleteEdit* edit,#002ITextDocument* text_object_model)#003: edit_(edit),#004text_object_model_(text_object_model) #005/ Freeze the screen.#006if

33、 (text_object_model_) #007long count;#008text_object_model_-Freeze(&count);#009#010#011#012AutocompleteEdit:ScopedFreeze:ScopedFreeze() #013/ Unfreeze the screen.#014/ NOTE: If this destructor is reached while the edit is being destroyed (for#015/ example, because we double-clicked the edit of a pop

34、up and caused it to#016/ transform to an unconstrained window), it will no longer have an HWND, and#017/ text_object_model_ may point to a destroyed object, so do nothing here.#018if (edit_-IsWindow() & text_object_model_) #019long count;#020text_object_model_-Unfreeze(&count);#021if (count = 0) 这里需

35、要手动地更新窗口的显示。#022/ We need to UpdateWindow() here instead of InvalidateRect() because, as#023/ far as I can tell, the edit likes to synchronously erase its background#024/ when unfreezing, thus requiring us to synchronously redraw if we dont#025/ want flicker.#026edit_-UpdateWindow();#027#028#029从上面的

36、代码可以看到构造函数里冻结,析构造函数里解冻结,如果需要就会自动更新窗口的显示。通过上面的分析,学会使用RichEdit的冻结窗口的输入,并且解冻结和更新窗口的显示,也同时学会使用智能指针来操作COM接口的方便性,最后还学会了使用栈对象的生命周期来方便对加锁和解锁的操作,以便降低代码的出错率。谷歌浏览器的源码分析(9)收藏为了处理字符消息实现自动完成的功能,这是怎么样实现的呢?其实是先记录字符消息响应前的字符串以及选中状态,接着再处理消息,最后才查询可能的输入,做出智能提示。#001void AutocompleteEdit:OnBeforePossibleChange() #002/ Rec

37、ord our state.记录当前已经输入的字符串。#003text_before_change_ = GetText();记录当前选中的字符位置。#004GetSelection(sel_before_change_);#005select_all_before_change_ = IsSelectAll(sel_before_change_);#006上面就保存字符消息响应前的状态,接着下来就是消息响应后的处理了,如下:#001bool AutocompleteEdit:OnAfterPossibleChange() #002/ Prevent the user from selecti

38、ng the phantom newline at the end of the#003/ edit.If they try, we just silently move the end of the selection back to#004/ the end of the real text.判断用户新选中状态。#005CHARRANGE new_sel;#006GetSelection(new_sel);#007const int length = GetTextLength();#008if (new_sel.cpMin length) | (new_sel.cpMax length)

39、 #009if (new_sel.cpMin length)#010new_sel.cpMin = length;#011if (new_sel.cpMax length)#012new_sel.cpMax = length;#013SetSelectionRange(new_sel);#014判断用户是否输入字符有变化。#015const bool selection_differs = (new_sel.cpMin != sel_before_change_.cpMin) |#016(new_sel.cpMax != sel_before_change_.cpMax);#017#018/

40、See if the text or selection have changed since OnBeforePossibleChange().#019const std:wstring new_text(GetText();#020const bool text_differs = (new_text != text_before_change_);#021#022/ Update the paste state as appropriate: if were just finishing a paste#023/ that replaced all the text, preserve

41、that information; otherwise, if weve#024/ made some other edit, clear paste tracking.#025if (paste_state_ = REPLACING_ALL)#026paste_state_ = REPLACED_ALL;#027else if (text_differs)#028paste_state_ = NONE;#029如果输入没有任何变化,就返回去。#030/ If something has changed while the control key is down, prevent#031/ c

42、trl-enter until the control key is released.When we do this, we need#032/ to update the popup if its open, since the desired_tld will have changed.#033if (text_differs | selection_differs) "(control_key_state_ = DOWN_WITHOUT_CHANGE) #035control_key_state_ = DOWN_WITH_CHANGE;#036if (!text_differs & !popup_-is_open()#037return false;/ Dont open the popup for no reason.#038 e

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号