背景

团队所开发的浏览器是根据Chromium进行开发的,有比较多的二次开发的代码,这样当浏览器晋级新版别时需求进行版别兼容,便是要把加的定制化代码搬迁到新的内核项目中,这是一项庞大,杂乱且容易出错的工程,和Android Framework开发中适配Android新版别的进程有些相似。那么怎样在这个适配进程中,进步适配的功率和适配后项目功用的安稳性,是一个非常值得考虑的问题。下面讲一讲浏览器在晋级内核的进程中怎么经过架构规划,来进步晋级内核的功率和功用的安稳性。这种思维也能够应用于Android Framewrok开发时适配新的版别,芯片定制开发,或许在第三方杂乱工程上进行二次开发的场景。

架构规划思路

我们浏览器项目Java工程二次开发的部分首要会集在书签,下载,前史,设置等模块,且改动较大。这些模块相对独立和安稳,在浏览器晋级到新的内核版别时,需求跟着搬迁到新的Chromium工程中,那么理清这些模块和Chromium工程的依靠联系是十分重要的,Chromium工程的代码会随着版别的不同而不同,因此在二次开发的模块代码中经过接口调用的方法去运用Chromium工程的才能是比较合理的,一起实际开发中,Chromium工程也需求去运用添加的事务模块的才能,这里同样能够选用接口调用的方法。根据上述的规划思维,项目中每个事务模块由两个Module构成,一个是API Module,首要界说了这个模块对外供给的接口,另一个Module首要包括的是该模块的详细事务代码以及对应的API Module中接口的完结部分,原有的Chromium工程规划成一个API Module和App Module,其间API模块界说了Chromium工程对其它模块供给了什么才能。这样规划之后,一切模块之间的交互都是经过接口调用进行的,模块之间解耦了。随着Chromium工程的晋级,二次开发的模块基本能够直接搬迁,需求关心的是以新的Chromium工程为根底去完结旧的Chromium工程的app_api Module中界说的接口,以及在新的Chromium工程中需求的当地去经过接口去调用其它事务模块的才能,关于哪些是需求的当地,下面以下载模块搬迁到新的工程为例子时,会讲到怎么去找到这些当地,这也体现了各个模块间经过接口调用的好处。以下载模块为例,模块间的规划如下图所示:

如何通过架构设计提高浏览器升级内核的稳定性和效率

download_api:接口模块,界说了下载模块对外暴露的才能。

download_impl:下载事务模块,依靠download_apiapp_api,并完结了**download_api **中界说的接口。

app_api:接口模块,里面界说了App模块对其它事务模块供给的才能,其间的BrowserDownloadModuleService接口类界说了对下载模块供给的才能。

app(browser) :浏览器(chromium工程)模块,依靠download_apiapp_api,并完结了app_api 模块中界说的接口。

模块搬迁流程

下面以下载模块搬迁到新的Chromium工程的进程为例,讲一讲怎么应用上面所说的规划,下面所说的App模块是指Chromium工程。

完结App模块对事务模块的功用依靠

首先是将下载模块的download_api Module从旧的浏览器项目中复制到新的项目工程中,然后在旧的浏览器项目中进行大局查找接口类DownloadModuleService.class(该类界说了下载模块对外供给了哪些才能),选中Module并挑选App.main模块进行过滤,如下图所示。

如何通过架构设计提高浏览器升级内核的稳定性和效率

这一步便是找出本来的App工程中哪些当地用到了下载模块的API,理清App模块对下载模块的依靠。能够看到原浏览器工程有16处调用了下载模块的功用,然后到新内核工程中依次找到对应的当地并调用相应的方法,假如Chromium版别之间差异较大,就需求梳理一下逻辑,定位到相应的当地进行修正。别的或许有时候的二次开发只是在Chromium本来的类的中进行部分修正,比较零散,这时候也能够考虑选用接口的方法进行调用,如下面的supportsDownloadCollection()所示,这样在晋级到新的内核进程中,经过在旧项目中查找一切的接口调用,就能够在Chromium中定位出需求修正的当地,避免了搬迁遗漏的状况,也必定程度上保障了功用的安稳性。

如何通过架构设计提高浏览器升级内核的稳定性和效率

完结事务模块对App模块的功用依靠

将app_api 模块从旧的项目中复制到新的工程中,一起从旧的App模块将BrowserDownloadModuleService的完结部分搬迁到新的工程中,BrowserDownloadModuleService(如下图1所示)接口中界说了下载模块依靠了App模块的哪些才能,接下来便是使BrowserDownloadModuleService接口的完结部分在新的工程和旧的工程中体现一样,完结这一步后就完结了事务模块对App模块的功用依靠。这部分的工作量与新的基线工程(Chromium工程)比照旧的工程改变量的大小正相关。别的,这里也有一些主张,比方事务模块依靠App模块的接口中界说的实体类最好是独自界说的类,即便Chromium工程中有相似的类,也不主张直接运用。像下载模块的DownloadInfo实体类,Chromium源码中有界说这个类,在BrowserDownloadModuleService接口中也需求运用相似的实体类,这里是独自界说了一个下载信息类,这样在Chromium源码改变时,相关的接口层也不需求变动,只需求在完结层做一次映射,将Chromium源码中的下载信息类转化成接口层对应的类就能够了,如下图2中createDownloadedInfo()所示。

如何通过架构设计提高浏览器升级内核的稳定性和效率

如何通过架构设计提高浏览器升级内核的稳定性和效率

调试和适配

在完结了上面两个部分后,就能够对整个下载模块进行功用调试了,对照测验Case一个个的过一遍。重点需求重视的的是所搬迁的模块和其它模块的相互依靠部分,这里是旧的App工程对下载模块的调用部分和App工程供给给下载模块的接口BrowserDownloadModuleService的完结部分。对于如何适配这里也有些小的主张,比方在调试下载模块中,发现旧版别的Chromium工程从native返回的DownloadInfo的FilePath是实际的存储途径,而新版别返回的FilePath是经过转化后的Uri,Uri是无法驱动本来的整个下载模块的逻辑的,需求转换成实际的存储途径,如下图中的convert2RealStorePath()所示,对下载途径进行了一次转化,其它一些适配也能够选用相似的方法,尽量减少对原有模块的修正,经过增加中间层来使输入保持和本来共同,以此来驱动原有的逻辑,因为原模块的功用已经经过多个线上版别的验证,安稳性有所保障。

如何通过架构设计提高浏览器升级内核的稳定性和效率

最后

至此,下载模块搬迁完结。首要的思维是梳理清楚参加的代码和原有的Chromium工程之间的联系,并将这种相互依靠经过接口调用的方法进行解耦,这样在搬迁到新的Chromium工程时,能清楚的找到新的Chromium工程中一切需求修正的当地,以及参加的事务模块依靠了Chromium工程的哪些才能。因为是以模块为单位进行搬迁,模块内部的逻辑是相对安稳的,项目的安稳性也得到必定程度的保障,一起在搬迁进程中,开发比较之前所需求重视的部分减少了,现在只需求重视模块间的依靠部分,搬迁进程也流程化了,晋级内核的功率得到进步。推而广之,在一些杂乱的项目上进行二次开发时,如Android Framework开发,芯片开发,解耦参加的代码和原有的工程依靠联系是要害,一起也能够参考上文说到的小的主张,从而整体进步新版别功用的安稳性和兼容新版别的功率。