当前位置:首页 > 芯闻号 > 充电吧
[导读]一、概述       之前有介绍过chromium的界面层的相关知识,这篇文章则是重点介绍chromium中书签这一个模块,不仅有界面层的知识,还会较多的介绍逻辑层的一些内容。接下来会详细介绍chro

一、概述
       之前有介绍过chromium的界面层的相关知识,这篇文章则是重点介绍chromium中书签这一个模块,不仅有界面层的知识,还会较多的介绍逻辑层的一些内容。接下来会详细介绍chromium中书签功能的详细实现。主要问题有:
              1、书签数据在硬盘和内存中存储结构;
              2、初始化过程;
              3、相关操作的实现步骤;
              4、线程模型;
              5、书签同步。

二、书签结构综述
        Bookmark界面层在..srcchromebrowseruiviewsbookmarks中实现。Bookmark逻辑层在..srcchromebrowserbookmarks 中实现,包括读写书签文件,书签导入导出等。
       书签在整个工程中是chrome特色功能,它包括三种类型,书签栏、其他、和“mobile”。书签栏管理用户创建的所有书签
       作为chromium拓展中心的一个功能,整体流程图如图:
 
    图1 书签整体流程图

       在书签模块中,其中主要的两个模块是底层数据处理和界面显示,具体实现分别在BookmarkModel和BookmarkBarView中,它们之间采用的是observer设计模式,BookmarkModel(具体目标),BookmarkBarView(具体观察者)。

三、书签存储结构
       书签的存储结构需要从配置文件中结构及内存中存储结构两方面分析。
       书签配置文件中存储在本地Bookmarks中,以JSON的格式存储。并在书签模块启动的时候load文件中的书签数据。本地JSON书签数据如下:
         "children": [ {
            "date_added": "12994954482846617",
            "id": "7",
            "name": "Google",
            "type": "url",
            "url": "http://www.google.com.hk/"
         },
       在内存中每个节点对应一个BookmarkNode。其中包含了favicon, id and type等节点信息。
       在BookmarkModel中定义了如下几个节点:
         BookmarkNode root_;
         BookmarkPermanentNode* bookmark_bar_node_;
         BookmarkPermanentNode* other_node_;
         BookmarkPermanentNode* mobile_node_;
       root_作为根节点,是书签栏中节点和“其他”文件夹中节点的父节点。BookmarkPermanentNode只是BookmarkNode一个简单的封装,用来管理书签栏及“其他”等这种固定的文件夹。

四、书签初始化及释放
       书签功能的初始化:可以分为两个部分,数据逻辑层和界面层。从上面的主流程图中我们可以看出,数据逻辑层先于界面层初始化,具体初始化流程如下:
       数据逻辑层:
       初始化流程,拓展中心统一初始化,在ExtensionService::InitEventRouters()中调用
       bookmark_event_router_.reset(new BookmarkExtensionEventRouter(
             BookmarkModelFactory::GetForProfile(profile_)));
             bookmark_event_router_->Init();
       最终在BookmarkModelFactory完成BookmarkModel的创建。另外,BookmarkExtensionEventRouter继承自BookmarkModelObserver,是BookmarkModel的一个具体观察者。会将bookmark中的修改通知装换成event传给extension system
       逻辑层初始化执行顺序如下图:

 
图2 书签数据逻辑层执行
       为防止阻塞UI线程,书签文件的加载是在一个后台进程中完成的,chromium启动的时候,主线程Post出一个文件加载的Task,同时传入了一个回调函数的指针参数,当消息中心处理这个Task时会调用之前传入的回调,并完成书签文件的加载接JSON数据的解析。注意这个步骤是在File加载线程中完成的。加载解析完成后,File加载线程会POST出一个Task,并将操作权交还给主线程,去完成后需初始化工作。
        书签文件的解析是在JSONFileValueSerializer中完成的,在这个里面会将JSON文件反序列化。并将其内容存入BookmarkLoadDetails中,供接下来的调用。

       界面层:
       BookmarkBarView类是BookmarkModel的具体观察者,负责书签数据的渲染布局等,与书签界面层相关的操作主要在这里面实现。
       BookmarkBarView由BrowserView统一管理,BrowserView不会主动创建BookmarkBarView,而是在之后执行需要书签的操作中,如UpdateUIForContents,若书签界面层尚未创建,则执行创建操作,否则跳过。

       书签模块的释放:同样重点完成数据逻辑层和界面层的释放。释放的过程和创建相反。先delete 管理界面模块的BookmarkBarView,这部分功能由BrowserView统一管理释放。之后再进一步delete管理逻辑层的模块BookmarkModel,这部分释放工作在配置文件管理中心统一释放。

五、书签操作执行流程
       书签界面层与逻辑层的类关系图如下。

 
   图3 界面层、逻辑层类关系图
    
       BookmarkModel继承自PofileDeyedService,因而可以实现在配置文件管理中心统一释放
       BookmarkBarView继承自DetachableToolbarView,是一个与Chrome frame分离的view控件。
       BookmarkModel与BookmarkBarView均继承自消息中心NotificationObserver,并会通过registrar_注册自己需要接受的通知。

       BookmarkModel类中的实现。它是是observer模式中的具体目标及数据逻辑层的核心实现。BookmarkModel对象需要通过 BookmarkModelFactory才能创建,而不能直接创建。
       BookmarkModel类管理者内存中的书签数据,也向外提供了很多的操作接口,如AddNode、RemoveAndDeleteNode、RemoveNode等。用户操作书签时,都会通过调用这些接口来修改书签内容。
       在BookmarkModel中通过定义一个BookmarkStorage的对象来操作书签的磁盘读写,上面提到的文件加载就是通过这个对象来执行的。另外,当书签数据与磁盘同步也在   这个里面完成,当用户修改了书签内容时,会调用其中的ScheduleSave()函数写回磁盘。
       书签磁盘读写的类图如下:
 

  图4 书签磁盘读写类图
       其中BookmarkLoadDetails是用来临时存储书签数据的对象。

       BookmarkBarView类派生自BookmarkModelObserver,是observer模式中一个具体的观察者。中完成书签界面展示以及部分用户操作。

       另外,书签栏内部的子文件夹显示也存在菜单栏的弹出,包括点击文件夹及拖动书签节点至文件夹都会弹出。BookmarkBarView中定义了两个菜单对书签栏的子菜单进行管理:
         BookmarkMenuController* bookmark_menu_;
         BookmarkMenuController* bookmark_drop_menu_;
       其中bookmark_menu_用于管理用户点击BookmarkBarView中的文件夹时弹出的菜单(BookmarkBarView是MenuButtonListener的子类,可以收听到这个事件)。bookmark_drop_menu_是用户拖拽一个node到文件夹上时弹出的菜单。


 
图5 书签右键菜单实现类图

       Chromium中书签最基本的操作有添加、删除、修改等。同时,用户操作书签的方式也有很多,如快捷键,主菜单,书签右键菜单等。书签操作的执行顺序基本如下。

 

图6 书签操作执行顺序


       书签的显示实现
       在chromium的代码中,每次调用网页时都会调用void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason),用以判断是否需要显示书签,书签有三种状态,SHOW(显示与地址栏不分离)、DETACHED(显示与地址栏分离)、HIDDEN(不显示)。
[cpp] view plaincopy void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason) {     BookmarkBar::State state;     // The bookmark bar is hidden in fullscreen mode, unless on the new tab page.     if (browser_defaults::bookmarks_enabled &&         profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) &&         (!window_ || !window_->IsFullscreen())) {       state = BookmarkBar::SHOW;     } else {       WebContents* web_contents = chrome::GetActiveWebContents(this);       BookmarkTabHelper* bookmark_tab_helper =           web_contents ? BookmarkTabHelper::FromWebContents(web_contents) : NULL;       if (bookmark_tab_helper && bookmark_tab_helper->ShouldShowBookmarkBar())         state = BookmarkBar::DETACHED;       else         state = BookmarkBar::HIDDEN;     }        // Only allow the bookmark bar to be shown in default mode.     if (!search_model_->mode().is_default())       state = BookmarkBar::HIDDEN;        if (state == bookmark_bar_state_)       return;        bookmark_bar_state_ = state;        if (!window_)       return;  // This is called from the constructor when window_ is NULL.        if (reason == BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH) {       // Don't notify BrowserWindow on a tab switch as at the time this is invoked       // BrowserWindow hasn't yet switched tabs. The BrowserWindow implementations       // end up querying state once they process the tab switch.       return;     }        BookmarkBar::AnimateChangeType animate_type =         (reason == BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE) ?         BookmarkBar::ANIMATE_STATE_CHANGE :         BookmarkBar::DONT_ANIMATE_STATE_CHANGE;     window_->BookmarkBarStateChanged(animate_type);   }  
       在这个函数中最终会调用window_->BookmarkBarStateChanged(animate_type),其中会调用到BrowserView的实现中,再由其中的bookmark_bar_view_来统一接手管理界面的工作。

       书签栏中点击打开网页
       当从书签栏中点击打开网页时,先会调用void BookmarkBarView::ButtonPressed函数,并在此函数中会调用page_navigator_->OpenURL(params);进一步调用WebContentsImple相应的方法来实现。

       当前页直接添加书签
       将当前页添加到书签则会调用void BookmarkCurrentPage(Browser* browser)(browser_commands.cc中的全局函数),再调用void BrowserView::ShowBookmarkBubble(const GURL& url, bool already_bookmarked)最终是在BookmarkBubbleView中完成。

六、书签线程模型
       在整个书签模块中,除了文件读取是在后台File线程中完成外,其余操作均在主线程中执行,线程执行方法与整个chromium的线程模型保持一致。
       为了保证书签文件在加载是不出现线程安全问题,chromium中设计了一个BookmarkStorage的中间层来读写书签文件,并在BookmarkStorage中定义了一个BookmarkLoadDetails,通过操作它来加载书签文件中的详细信息。加载完成后回调到主线程,并把所有权交还给BookmarkModel。但BookmarkModel中没有对BookmarkLoadDetails的引用,不能直接操作其中的内容,这样就确保解决了线程可能带来的问题。

七、登陆后书签同步
       用户登陆成功后,数据同步中心会对相关数据进行同步,书签也包括在内。在Chromium中会由browser_sync同步中心统一管理用户同步相关操作。BookmarkModelAssociator负责实现bookmark model 和sync model之间的联系算法、为sync node 及bookmark node之间的相互获取提供方法。同步完成后最终会调用BookmarkModel的相关方法来实现书签的更新。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

前一段参与了一个项目,项目内部使用了chromium作为基础库,这也是我第一次接触chromium,到现在差不多半年时间,这里说说使用心得。

关键字: chromium 多线程任务

微软今天宣布,它为Linux提供了微软edge的预发布版本,现在所有主要的办公室和平台都可以使用。动机。动机他们使用Ubuntu、Debian、Fedora和openSUSE的版本。现在就可以下载Microsof...

关键字: chromium edge Linux

三星Internet是最受欢迎的互联网浏览器。Chrome包含许多其他谷歌Chrome没有的功能。上个月早些时候,浏览器对beta字符串进行了一次重要的更新,它类似于chrome12.1.2.5,现在已经安装在一...

关键字: internet Android chromium

8 月 8 日消息 据 windowslatest 报道,上周五一名独立的开发者在微软商店上发布了开源的 Chromium 浏览器。这款浏览器是由一个名为 "Store Ports" 的发行商非正式

关键字: chromium 微软 浏览器

谷歌的Android for Chrome小组成员本周参加了AMA。 后来有网友评论,软件开发人员,技术程序经理、交互设计师、产品支持经理和开发律师组成的团队回答了许多问题。

关键字: Android chromium polymer

安装自动Windows 10更新补丁KB4559309后,一些用户抱怨说,在他们的计算机桌面上启动会花费更长的时间。 根据社区论坛主持人的说法,用户已经在Microsoft的社区论坛上报告了此问题,并且Microsoft...

关键字: chromium Linux Windows

原标题:微软将开始向更多Windows 10用户推送新版Edge 来源:cnBeta.COM 对于消费者和企业来说,传统版微软Edge时代将在未来几个月内结束。今年1月,微软宣布Chromium Ed

关键字: chromium Windows 微软 浏览器

目前,苹果仅在Mac、iPhone和iPad设备上提供 Safari 浏览器,近日,一名苹果员工邀请Chromium开发人员在Chromium 80的问题追踪工具中激活“智能跟踪预防”技术的标记。

关键字: chromium 浏览器

近日,据外媒报道,基于Chromium内核打造的全新Microsoft Edge浏览器将于2020年1月15日正式发布! 此前也有消息称,微软希望当Windows 10 20H1也就是2020年春季

关键字: chromium edge 微软 microsoftedge

11月3日消息 据the Verge消息,微软为Chromium版Edge浏览器准备了新的Logo,目前它被发现隐藏于最新的Canary版本中的迷你复活节彩蛋游戏之中。新的Logo样式变得更加圆润且富

关键字: chromium 微软 edge浏览器
关闭
关闭