Android WebView加载Chromium动态库的过程分析

Android WebView加载Chromium动态库的过程分析

ID:39464513

大小:271.50 KB

页数:27页

时间:2019-07-03

Android WebView加载Chromium动态库的过程分析_第1页
Android WebView加载Chromium动态库的过程分析_第2页
Android WebView加载Chromium动态库的过程分析_第3页
Android WebView加载Chromium动态库的过程分析_第4页
Android WebView加载Chromium动态库的过程分析_第5页
资源描述:

《Android WebView加载Chromium动态库的过程分析》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、AndroidWebView加载Chromium动态库的过程分析Chromium动态库的体积比较大,有27M左右,其中程序段和数据段分别占据25.65M和1.35M。如果按照通常方式加载Chromium动态库,那么当有N个正在运行的App使用WebView时,系统需要为Chromium动态库分配的内存为(25.65+Nx1.35)M。这是非常可观的。为此,Android使用了特殊的方式加载Chromium动态库。本文接下来就详细分析这种特殊的加载方式。为什么当有N个正在运行的App使用WebView时,系统需要为Chromium动态库分配的内存为(25.65+Nx

2、1.35)M呢?这是由于动态库的程序段是只读的,可以在多个进程之间进行共享,但是数据段一般是可读可写的,不能共享。在1.35M的数据段中,有1.28M在Chromium动态库加载完成后就是只读的。这1.28M数据包含有C++虚函数表,以及指针类型的常量等,它们在编译的时候会放在一个称为GNU_RELRO的Section中,如图1所示:如果我们将该GNU_RELROSection看作是一般的数据段,那么系统就需要为每一个使用了WebView的App进程都分配一段1.28M大小的内存空间。前面说到,这1.28M数据在Chromium动态库加载完成后就是只读的,那么有没

3、有办法让它像程序段一样,在多个App进程之间共享呢?只要能满足一个条件,那么答案就是肯定的。这个条件就是所有的App进程都在相同的虚拟地址空间加载Chromium动态库。在这种情况下,就可以在系统启动的过程中,创建一个临时进程,并且在这个进程中加载Chromium动态库。假设Chromium动态库的加载地址为BaseAddress。加载完成后,将Chromium动态库的GNU_RELROSection的内容Dump出来,并且写入到一个文件中去。以后App进程加载Chromium动态库时,都将Chromium动态库加载地址BaseAddress上,并且使用内存映射的

4、方式将前面Dump出来的GNU_RELRO文件代替Chromium动态库的GNU_RELROSection。这样就可以实现在多个App进程之间共享Chromium动态库的GNU_RELROSection了,如图2所示:从前面一文可以知道,所有的App进程都是由Zygote进程fork出来的,因此,要让所有的App进程都在相同的虚拟地址空间加载Chromium动态库的最佳方法就是在Zygote进程的地址空间中预留一块地址。还有两个问题需要解决。第一个问题是要将加载后的Chromium动态库的GNU_RELROSection的内容Dump出来,并且写入到一个文件中去。

5、第二个问题是要让所有的App进程将Chromium动态加载在指定位置,并且可以使用指定的文件来代替它的GNU_RELROSection。这两个问题都可以通过Android在5.0版本提供的一个动态库加载函数android_dlopen_ext解决。接下来,我们就结合源码,分析Zygote进程是如何为App进程预留地址加载Chromium动态库的,以及App进程如何使用新的动态库加载函数android_dlopen_ext加载Chromium动态库的。从前面一文可以知道,Zygote进程在Java层的入口函数为ZygoteInit类的静态成员函数main,它的实现如

6、下所示:[java]viewplaincopypublicclassZygoteInit{......publicstaticvoidmain(Stringargv[]){try{.......preload();.......if(startSystemServer){startSystemServer(abiList,socketName);}......runSelectLoop(abiList);......}catch(MethodAndArgsCallercaller){......}catch(RuntimeExceptionex){......}}

7、......}这个函数定义在文件frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中。ZygoteInit类的静态成员函数main在启动System进程以及使得Zygote进程进入运行状态之前,首先会调用另外一个静态成员函数preload预加载资源。这些预加载的资源以后就可以在App进程之间进行共享。ZygoteInit类的静态成员函数preload在预加载资源的过程中,就会为Chromium动态库预保留加载地址,如下所示:[java]viewplaincopypublicclassZ

8、ygote

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。