Android WebView启动Chromium渲染引擎的过程分析Word格式文档下载.docx
- 文档编号:17966718
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:58
- 大小:143.93KB
Android WebView启动Chromium渲染引擎的过程分析Word格式文档下载.docx
《Android WebView启动Chromium渲染引擎的过程分析Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《Android WebView启动Chromium渲染引擎的过程分析Word格式文档下载.docx(58页珍藏版)》请在冰豆网上搜索。
Chromium以后需要请求Browser端执行某一个操作时,就可以向这个BrowserMainLoop发送一个Task。
这个Task最终会在App进程的UI线程中调度执行。
AndroidWebView启动Chromium的Render端,实际上就是在当前的App进程中创建一个线程。
以后网页就由这个线程负责加载和渲染。
这个线程称为In-ProcessRendererThread。
由于Chromium的GPU端实现在App的RenderThread中,这个RenderThread是由App负责启动的,因此Chromium无需启动它。
不过,Chromium里的android_webview模块会启动一个DeferredGpuCommandService服务。
当Chromium的Browser端和Render端需要执行GPU操作时,就会向DeferredGpuCommandService服务发出请求。
这时候DeferredGpuCommandService服务又会通过App的UI线程将请求的GPU操作提交给App的RenderThread执行。
这一点可以参考前面一文的描述。
我们在接下来的一篇文章也会对Chromium的Browser端和Render端执行GPU操作的过程进行详细的分析。
接下来我们就结合源码,分析AndroidWebView启动Chromium的Browser端和Render端的过程。
对于GPU端,我们仅仅分析与它相关的DeferredGpuCommandService服务的启动过程。
在接下来一篇文章分析AndroidWebView执行GPU命令的过程时,我们再对GPU端进行更详细的分析。
我们首先分析AndroidWebView启动Chromium的Browser端的过程。
前面提到,WebView会在内部创建一个类型为WebViewChromium的Provider。
有了这个Provider之后,WebView就可以调用它的成员函数init启动Chromium的Browser端,如下所示:
[java]viewplaincopy
classWebViewChromiumimplementsWebViewProvider,
WebViewProvider.ScrollDelegate,WebViewProvider.ViewDelegate{
......
publicvoidinit(finalMap<
String,Object>
javaScriptInterfaces,
finalbooleanprivateBrowsing){
//Wewilldeferrealinitializationuntilweknowwhichthreadtodoiton,unless:
//-weareonthemainthreadalready(commoncase),
//-theappistargeting>
=JBMR2,inwhichcasecheckThreadenforcesthatallusage
//comesfromasinglethread.(NoteinJBMR2thisexceptionwasinWebView.java).
if(mAppTargetSdkVersion>
=Build.VERSION_CODES.JELLY_BEAN_MR2){
mFactory.startYourEngines(false);
checkThread();
}elseif(!
mFactory.hasStarted()){
if(Looper.myLooper()==Looper.getMainLooper()){
mFactory.startYourEngines(true);
}
mRunQueue.addTask(newRunnable(){
@Override
publicvoidrun(){
initForReal();
});
}
这个函数定义在文件frameworks/webview/chromium/java/com/android/webview/chromium/WebViewChromium.java中。
WebViewChromium类的成员变量mFactory指向的是一个WebViewChromiumFactoryProvider对象。
WebViewChromium类的成员函数init通过调用这个WebViewChromiumFactoryProvider对象的成员函数startYourEngines启动Chromium渲染引擎的Browser端。
在Android4.3之前,WebView只能在App的UI线程中创建。
相应地,WebView也只能在App的UI线程中启动Chromium渲染引擎的Browser端。
这时候WebViewChromium类的成员函数init会传递一个参数true给WebViewChromiumFactoryProvider类的成员函数startYourEngines,表示如果当前线程如果不是UI线程,那么就需要向UI线程发出一个通知,让UI线程执行启动Chromium渲染引擎的Browser端的操作。
在Android4.3及以后,WebView也允许在App的非UI线程中创建。
这时候WebView允行在App的非UI线程中启动Chromium渲染引擎的Browser端。
因此,WebViewChromium类的成员函数init就会传递一个参数false给WebViewChromiumFactoryProvider类的成员函数startYourEngines。
一般情况下,WebView都是在App的UI线程中创建的。
为了简单起见,我们只考虑这种情况。
WebViewChromium类的成员函数init调用WebViewChromiumFactoryProvider类的成员函数startYourEngines启动了Chromium渲染引擎的Browser端之后,接下来还会向App的UI线程的消息队列发送一个Runnable。
当该Runnable被执行的时候,它就会调用WebViewChromium类的成员函数initForReal创建图1所示的AwContents对象。
有了这个AwContents对象之后,后面就可以通过它来加载指定的URL了。
接下来,我们首先分析WebViewChromiumFactoryProvider类的成员函数startYourEngines启动Chromium渲染引擎的Browser端的过程,然后再分析WebViewChromium类的成员函数initForReal为WebView创建AwContents对象的过程。
WebViewChromiumFactoryProvider类的成员函数startYourEngines的实现如下所示:
publicclassWebViewChromiumFactoryProviderimplementsWebViewFactoryProvider{
voidstartYourEngines(booleanonMainThread){
synchronized(mLock){
ensureChromiumStartedLocked(onMainThread);
这个函数定义在文件frameworks/webview/chromium/Java/com/android/webview/chromium/WebViewChromiumFactoryProvider.java中。
WebViewChromiumFactoryProvider类的成员函数startYourEngines调用另外一个成员函数ensureChromiumStartedLocked检查Chromium渲染引擎的Browser端是否已经启动。
如果还没有启动,那么就会进行启动,如下所示:
privatevoidensureChromiumStartedLocked(booleanonMainThread){
if(mStarted){//Early-outforthecommoncase.
return;
Looperlooper=!
onMainThread?
Looper.myLooper():
Looper.getMainLooper();
ThreadUtils.setUiThread(looper);
if(ThreadUtils.runningOnUiThread()){
startChromiumLocked();
//WemustposttotheUIthreadtocoverthecasethattheuserhasinvokedChromium
//startupbyusingthe(thread-safe)CookieManagerratherthancreatingaWebView.
ThreadUtils.postOnUiThread(newRunnable(){
while(!
mStarted){
try{
//Important:
wait()releases|mLock|theUIthreadcantakeit:
-)
mLock.wait();
}catch(InterruptedExceptione){
//Keeptrying...eventuallytheUIthreadwillprocessthetaskwesentit.
这个函数定义在文件frameworks/webview/chromium/java/com/android/webview/chromium/WebViewChromiumFactoryProvider.java中。
如果Chromium渲染引擎的Browser端已经启动,那么WebViewChromiumFactoryProvider类的成员变量mStarted的值就会等于true。
在这种情况下,WebViewChromiumFactoryProvider类的成员函数ensureChromiumStartedLocked什么也不用做就可以返回。
另一方面,如果Chromium渲染引擎的Browser端还没有启动,那么WebViewChromiumFactoryProvider类的成员函数ensureChromiumStartedLocked首先会根据参数onMainThread确定Chromium渲染引擎的Browser端要在哪个线程中运行。
当参数onMainThread的值等于true的时候,就表示Chromium渲染引擎的Browser端要在App的UI线程中运行。
这时候如果当前线程不是App的UI线程,那么WebViewChromiumFactoryProvider类的成员函数ensureChromiumStartedLocked就会向App的UI线程的消息队列发送一个Runnable。
当该Runnable被执行的时候,才会启动Chromium渲染引擎的Browser端。
在这种情况下,当前线程也会等待App的UI线程启动完成Chromium渲染引擎的Browser端。
当参数onMainThread的值等于true的时候,如果当前线程刚好也是App的UI线程,那么WebViewChromiumFactoryProvider类的成员函数ensureChromiumStartedLocked就可以马上启动Chromium渲染引擎的Browser端。
当参数onMainThread的值等于false的时候,不管当前线程是否App的UI线程,都表示Chromium渲染引擎的Browser端要在它里面运行。
因此,这时候WebViewChromiumFactoryProvider类的成员函数ensureChromiumStartedLocked都会马上启动Chromium渲染引擎的Browser端。
无论是上述的哪一种情况,用来运行Chromium渲染引擎的Browser端的线程都会通过调用ThreadUtils类的静态成员函数setUiThread记录起来。
以后WebView都需要在该线程中访问Chromium渲染引擎。
WebViewChromiumFactoryProvider类的成员函数ensureChromiumStartedLocked是通过调用另外一个成员函数startChromiumLocked启动Chromium渲染引擎的Browser端的,如下所示:
privatevoidstartChromiumLocked(){
AwBrowserProcess.start(ActivityThread.currentApplication());
WebViewChromiumFactoryProvider类的成员函数startChromiumLocked通过调用AwBrowserProcess类的静态成员函数start启动Chromium渲染引擎的Browser端的,如下所示:
publicabstractclassAwBrowserProcess{
publicstaticvoidstart(finalContextcontext){
//WemustposttotheUIthreadtocoverthecasethattheuser
//hasinvokedChromiumstartupbyusingthe(thread-safe)
//CookieManagerratherthancreatingaWebView.
ThreadUtils.runOnUiThreadBlocking(newRunnable(){
BrowserStartupController.get(context).startBrowserProcessesSync(
BrowserStartupController.MAX_RENDERERS_SINGLE_PROCESS);
}catch(ProcessInitExceptione){
这个函数定义在文件external/chromium_org/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java中。
前面提到,用来运行Chromium渲染引擎的Browser端的线程会通过ThreadUtils类的静态成员函数setUiThread记录起来。
AwBrowserProcess类的静态成员函数start为了确保Chromium渲染引擎的Browser端在该线程中启动,会通过调用ThreadUtils类的静态成员函数runOnUiThreadBlocking检查当前线程是否就是该线程。
如果是的话,那么就会直接启动。
否则的话,会向该线程的消息队列发送一个Runnable。
当该Runnable被执行的时候,再启动Chromium渲染引擎的Browser端。
AwBrowserProcess类的静态成员函数start是通过调用当前App进程中的一个BrowserStartupController单例对象的成员函数startBrowserProcessesSync来启动Chromium渲染引擎的Browser端的。
这个BrowserStartupController单例对象可以通过调用BrowserStartupController类的静态成员函数get获得。
AwBrowserProcess类的静态成员函数start在启动Chromium渲染引擎的Browser端的时候,会指定一个BrowserStartupController.MAX_RENDERERS_SINGLE_PROCESS参数。
这个参数的值等于0,表示要启动一个单进程架构的Chromium渲染引擎。
接下来,我们就继续分析Chromium渲染引擎的Browser端的启动过程,也就是BrowserStartupController类的成员函数startBrowserProcessesSync的实现,如下所示:
publicclassBrowserStartupController{
publicvoidstartBrowserProcessesSync(intmaxRenderers)throwsProcessInitException{
//Ifalreadystartedskiptocheckingtheresult
if(!
mStartupDone){
mHasStartedInitializingBrowserProcess){
prepareToStartBrowserProcess(maxRenderers);
if(contentStart()>
0){
//Failed.Thecallbacksmaynothaverun,sorunthem.
enqueueCallbackExecution(STARTUP_FAILURE,NOT_ALREADY_STARTED);
这个函数定义在文件external/chromium_org/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java中。
当BrowserStartupController类的成员变量mStartupDone的值等于true的时候,就表示Chromium渲染引擎的Browser端已经启动了。
这时候BrowserStartupController类的成员函数startBrowserProcessesSync就什么也不做就直接返回。
另一方面,如果Chromium渲染引擎的Browser端还没有启动。
这时候BrowserStartupController类的成员函数startBrowserProcessesSync就会调用另外一个成员函数contentStart进行启动。
在启动Chromium渲染引擎的Browser端
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android WebView启动Chromium渲染引擎的过程分析 WebView 启动 Chromium 渲染 引擎 过程 分析