打造专属的Chromium for Android

来源:互联网 发布:书生空谈 知乎 编辑:程序博客网 时间:2024/05/16 01:21

打造专属的Chromium for Android

自从写了上篇《chrome 源码研究启航篇》后,到今天已经有了近一个月的时间,这段时间做了啥呢?研究到啥程度了呢?后续节奏是否有调整呢?

针对上边疑问,下面做逐个解答:

一,这段时间做了啥?

总体来讲,这段时间主要利用闲余在编译和熟悉源码,完成了对源码的编译和Gradle构建,并将项目开源,命名为:公英小蒲。Git地址:https://github.com/derry/delion.git

具体的:

   1,获得源码

   和预期计划的一样,要深入研究Chrome首先要拿到完整的代码,进行完整的编译,先从宏观上搞清楚他的整体结构,搞清楚他开源的代码是否完整可用,进而确定下一步研究思路。

   获取源码官方有文档,http://dev.chromium.org/developers/how-tos/get-the-code,获取过程虽然等待时间漫长但总体还算比较顺利。fetch --nohooks android 完成后,代码基本就都拉下来了。过程中如果中断了,可以执行gclient sync继续。

因为这时候使用的—nohooks,所以真正编译需要的资源这时候还没有下。这一步一般没啥问题。

   2,编译

代码下完后,下一步选择编译方式:使用GYP或GN。

GYP的编译方式出来的比较早(网上查找也基本都是GYP的编译,我们现在项目里的编译方式就是GYP,市面上开源的如365浏览器也是,早期版本GYP方式确实可行,为什么说早期可行看后边)。我优先选择了使用GYP方式编,考虑这样的话还有成功的案例可以参考。(后来为此决定付出了折腾一晚上的代价)

根据官方说明:

echo "{'GYP_DEFINES': 'OS=android target_arch=arm', }" > chromium.gyp_env

指定编译类型。

然后运行gclient runhooks 获取真正的GYP需要的构建所需的资源。

正常情况执行后会把需要的所有资源下载下来。但是实践过程中发现里面有坑。

   经历的那些坑:

    a,运行gclient runhooks

         If you really want to run this, either run

         `python build/gyp_chromium.py`explicitly by hand

         or set the environment variable        GYP_CHROMIUM_NO_ACTION=0.

    b,You have PROXYvalues set in your environment, but gsutil in depot_tools does not (yet) obeythem.

 RESOLVED
Create a Boto configuration file somewhere with the following contents: 

  [Boto] 
 proxy = example-host 
  proxy_port = port number 

After that, point the NO_AUTH_BOTO_CONFIG environment variable to the file you created: 

 export NO_AUTH_BOTO_CONFIG=/path/to/proxy_webrtc.boto 

    c,设置GYP编译,运行gclientrunhooks 报文件找不到(most_visited_sites.cc,most_visited_sites.h) IOError:[Errno 2] No such file or directory:'browser/android/ntp/most_visited_sites.cc'

折腾一圈后总会回到找不到most_visited_sites.cc这个文件这。具体去查这个文件, 在历史版本里确实是有的, 在新版本里也确实没有。查看GIT记录有发现有删除了该文件的记录,排除了各种可能后,最后决定放弃这种编译方式,现在Google也不推崇这种方式,建议使用GN编译。(推测是从google推崇了GN后,后续新的版本GYP的编译脚本没有同步上)

在GYP编译的问题上折腾了一晚无果后,选择GN来编译(官方推荐使用该种方式,构建效率大大提高且较强的支持增量编译),根据官方文档,使用GN编一路走下来非常顺利。

开始使用分支最新的代码编,后来发现打出APK安装运行有问题(beta版本不稳定的原因),最后切到了最新Tag尝试编译(54.0.2789.1)。结果比较理想, 编译OK,运行OK。

3,使用gradle构建Chromium项目

完整编译完整个项目还是比较兴奋的,但这只是开始,如何构建成开发环境下可调的呢?(总不能靠sublime查着看,那只能满足研究的需求,解决不了要方便的调试和开发的需求)

开始考虑使用简单直接的方式,保持原有的源码结构,在各项目里添加gradle文件,顺着脚本构建的流程,把项目整理理顺,实现整体的项目Control。

但是真正实践起来,感觉比较吃力,主要原因是一方面涉及的构建问题太多,另外就是对项目代码还不太了解。并且中间因为解决编译问题做得改动不容易记录,即使最后构建成功,以后想升级版本也会比较被动。所以折腾了一晚上,把整体架子搭出来但是编译还各种问题的时候,果断放弃了这条路。想一口气吃个胖子真心没那么容易。

还有一种方式就是:不基于原有的项目结构搞了,单独构建一套简单的。通过摘取有用的资源,直接使用编译过程中生成的中间文件(jar,so,src等),最小限度的改动项目的原有代码。这样等整体构建成功后,再根据研究进度,需要研究哪块,把哪快源码形式构建进来。

这样可以最大限度的使用源码自己构建的结果,减少代码层面改动,在构建成本上能省不少功夫。通过搭起大框架,填充编译结果文件,然后遇到啥问题解决啥问题。整体来讲,这条路绝对是最简单的。如果这条路走不通,也就没得其他路可走了。

通过开始的分析发现了因为命名空间的原因,资源放置分开是比较合适的,比对了下最新的代码,结构变化不大,所以最后延用了365的结构。(有365这个前行者感觉还是蛮好的。虽然该踩的坑还是要自己去踩,但是比看不到方向的往前走感觉好多了,由他证明了这条路是可行的,并给出了思路,对此心存感激)

使用的项目的结构如下:


4,编译过程中趟的那些坑

构建方向确定了,剩下就是一步步趟坑了(最耗时间的就耗在了这一步)

根据构建过程中遇到的问题顺序:

1,org.chromium.base.BuildConfig 找不到

修复方式:

创建base Modules ,最后提示:NoSuchMethodError:org.chromium.base.BuildConfig.isMultidexEnabled

发现该文件是动态生成的(具体参考

https://groups.google.com/a/chromium.org/forum/#!topic/chromium-checkins/auM6vUukpno

文件在Gen 文件夹找到并拷贝

2,缺少local_paks(ChromeApplication.Class中报array.locale_paks 找不到)

修复方式:

新建locales.xml 添加array.locale_paks ,指定

<item>@raw/zhcn</item>

<item>@raw/enus</item>

3, floats找不到(NoClassDefFoundError:org.chromium.chrome.R$floats)

   而代码中查看floats作为resource type 使用,编译环境下直接报错

修复方式:floats改为dimen。

本来想先不用代码,直接使用chrome_jar,但是因为floats的问题不得不改代码,所以接下来使用工程代码替换chrome_jar。

4,使用工程代码替换chrome_jar会报一些列的类找不到,原因是很多配置类是在构建过程总动态生成的,所以想编译成功必须要类倒进来。(缺的类有很多,但都在chrome_jar中能找到,所以处理起来比较简单)

5,styleable.AppCompatTheme找不到

都使用最新的support包(具体参照项目)

6,  NativeLibraries类找不到

发现该类是动态生成的,新建文件,把值填充进去。

7, Unable to load library:libaccessibility.cr.so

 更新so文件,使用未压缩的文件

8, Unable to instantiateapplication com.android.tools.fd.runtime.BootstrapApplication :

Disable Instant Run( Preferences -> Build,Execution, Deployment -> Instant Run -> Enable Instant Run)

9,locale_paks 资源找不到:排查一圈发现问题出现在问题2的修复上,通过搜脚本(locale_pak_resources.py)发现需要文件小写,并改'-’变’_’ 最终改资源名需为“zh_cn.lpak”,”en_us.lpak"

10,Suppressed:java.lang.ClassNotFoundException: org.chromium.mojom.device.BatteryMonitor

引入相应文件

解决上述问题后,编译运行,OK一切正常。

5,解决了完整编译的工作,下面就是打造专属浏览器了

制定包名:com.delion.browser

浏览器命名:公英小蒲

  • 取名公英小蒲,寓意该项目是基于Chromium衍生的一枚“蒲公英“的种子,希望能秉承Chromium的开源精神和强大的技术基因,以及做为种子的传播使命,在国内生根发芽,茁壮成长,能够将前沿的相关知识分享扩散出去,应用在更多的场景和领域。

至此,公英小蒲浏览器正式诞生。

二,目前研究到啥程度了呢?

所谓万事开头难,目前阶段还出在刚开完了头的阶段。实现了项目的完整编译,并将项目开源。

剩下的就是一步步分析和定制了。当然定期跟进最新代码也是必不可少的工作。

过程中熟悉了Chromium源码的整体结构,但也感受到了他的发展速度,相比对比早期的版本,他的代码的改动量和频率都还是很大的。万里长征这才刚刚开始。

过程中遇到的问题的前期修复主要靠全局查找,到后期发现顺着GN的构建流程是最有效的,很多中间文件配置文件都是通过脚本动态生成的。顺着脚本的实现思路走,是最有效的。相关构建资料目前可以说还没有,要缕顺构建过程,脚本就是最好的老师。而通过他们也可以看出,超过百人的开发团队去维护的项目,强大的脚本能力是必不可少的。所幸这点是我的强项(Ant构建,Gradle构建,Python脚本等在平时的项目管理过程中都会用到,所以炼出来了)。

后边用到脚本的地方还会很多,比如:

1,      最理想功能的改动就是靠脚本去改,这样以后更新代码,冲突会降到最低。

2,      最理想的构建过程也是靠脚本,只要能人工操作的流程,需要频繁操作的,都可以写成脚本,操作成本降到最低。

针对这一点,后续的各功能开发和维护过程中会逐步的体现出来。

 

三,后续怎样的节奏?

目前来看节奏不会变,延续开始构想的思路,以研究和解决问题为目的,过程会比较难,但会做到底 。

另外讲一下要把过程写出来和开源的目的:

1,      项目庞大,不是一个人就可以完全Hold住的,学习的速度赶不上谷歌一百多号技术开发变化的速度,需要一帮志同道合的人一起研究一起弄。共同成长。(最好是有这方面基础在研究这方面的人)

2,      准备把专属的项目《公英小蒲》持续做下去,无任何商业目的和功利掺杂,自驱动的纯把浏览器作为一个中立的工具性产品去打磨。以简单好用为第一宗旨去发展。打造专属品牌。

3,      浏览器开发涉及的技术非常广,有很高的研究价值,对谷歌而言这也是战略级的产品。跟进他的发展节奏持续研究和开发,可以接触到谷歌第一手的技术资料和使用这样的世界级应用框架。

4,     《公英小蒲》项目构建初衷是方便研究Chromium源码,推广相关前沿技术,构建独立应用的同时,将成果应用到其他项目。目前笔者负责着国内某手机浏览器的项目管理和开发工作。针对线上应用的业务和实现技术不便透露(有研究成果也会体现到公司专利上),这也是为什么之前博客不撰写这方面文章的原因,技术交流没有问题。《公英小蒲》基于最新的chromium构建,基于源码分享源码,秉承开源开放的天性,最为适合作为研究性应用开源。

具体方向思路:

1,      完整编译构建chromium_Android项目(Done)

2,      项目开源,携手更多的同行者(doing)

3,      业务定制,通过分析各主要模块,并实现痛点问题的逐步定制。(过程都体现在开源项目上)

4,      深度挖掘,针对V8引擎,硬件加速,VR等逐步挖掘

分享节奏(保证工作情况下,利用闲余时间):

1,      开源项目持续更新

2,      博客不定期更新(整块业务技术实现分析,研究轨记,定期总结等)


1 0
原创粉丝点击