webview创建过程分析(四)

本文详细剖析了WebView在Android中的创建过程,从WebContents的构建到WebContentsImpl的初始化,再到FrameTree、RenderFrameHostManager的创建。文章深入探讨了SiteInstance、RenderViewHost和RenderFrameHost的创建逻辑,揭示了WebView如何承载网页内容的关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在前面webview创建过程分析(三)中我们了解了AwContents的初始化过程,其中还有一个点也就是native的初始化部分没有将,今天主要来看下AwContents的native是如何实现的。

private static native long nativeInit(AwBrowserContext browserContext);

AwContents会调用nativeInit方法来进行native层的初始化工作,而AwContents对应的jni层代码在AwContents_jni.h文件中。natveInit对应的jni代码为

JNI_GENERATOR_EXPORT jlong Java_org_chromium_android_1webview_AwContents_nativeInit(
    JNIEnv* env,
    jclass jcaller,
    jobject browserContext) {
  return JNI_AwContents_Init(env, base::android::JavaParamRef<jobject>(env, browserContext));
}

我们来看下JNI_AwContents_Init的实现,实现代码在aw_contents.cc

static jlong JNI_AwContents_Init(JNIEnv* env,
                                 const JavaParamRef<jobject>& browser_context) {
  // TODO(joth): Use |browser_context| to get the native BrowserContext, rather
  // than hard-code the default instance lookup here.
  std::unique_ptr<WebContents> web_contents(content::WebContents::Create(
      content::WebContents::CreateParams(AwBrowserContext::GetDefault())));
  // Return an 'uninitialized' instance; most work is deferred until the
  // subsequent SetJavaPeers() call.
  return reinterpret_cast<intptr_t>(new AwContents(std::move(web_contents)));
}

这里最主要的逻辑就是创建了WebContents对象和AwContents对象,接下来我们看下这两个对象创建过程中都涉及到哪些逻辑

WebContents创建过程

1.构建WebContents::CreateParams参数

WebContents::CreateParams::CreateParams(BrowserContext* context)
    : CreateParams(context, nullptr) {}

WebContents::CreateParams::CreateParams(BrowserContext* context,
                                        scoped_refptr<SiteInstance> site)
    : browser_context(context),
      site_instance(std::move(site)),
      opener_render_process_id(content::ChildProcessHost::kInvalidUniqueID),
      opener_render_frame_id(MSG_ROUTING_NONE),
      opener_suppressed(false),
      created_with_opener(false),
      routing_id(MSG_ROUTING_NONE),
      main_frame_routing_id(MSG_ROUTING_NONE),
      main_frame_widget_routing_id(MSG_ROUTING_NONE),
      initially_hidden(false),
      guest_delegate(nullptr),
      context(nullptr),
      renderer_initiated_creation(false),
      desired_renderer_state(kOkayToHaveRendererProcess),
      starting_sandbox_flags(blink::WebSandboxFlags::kNone) {}

这个参数的创建过程主要是进行一些变量的初始化。

2.WebContents::Create方法分析

std::unique_ptr<WebContents> WebContents::Create(
    const WebContents::CreateParams& params) {
  return WebContentsImpl::CreateWithOpener(params, FindOpenerRFH(params));
}

这里主要是调用WebContentsImpl的CreateWithOpener方法

std::unique_ptr<WebContentsImpl> WebContentsImpl::CreateWithOpener(
    const WebContents::CreateParams& params,
    RenderFrameHostImpl* opener_rfh) {
  TRACE_EVENT0("browser", "WebContentsImpl::CreateWithOpener");
  FrameTreeNode* opener = nullptr;
  if (opener_rfh)
    opener = opener_rfh->frame_tree_node();
  std::unique_ptr<WebContentsImpl> new_contents(
      new WebContentsImpl(params.browser_context));

  ........
  new_contents->Init(params);
  return new_contents;

从这里可以知道前面需要的WebContents对象实际上是WebContentsImpl

这里主要分为两步:

1.创建WebContentsImpl

2.调用WebContentsImpl的Init方法

创建WebContentsImpl

WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
    : delegate_(nullptr),
      controller_(this, browser_context),
      render_view_host_delegate_view_(nullptr),
      created_with_opener_(false),
      node_(this),
      frame_tree_(new NavigatorImpl(&controller_, this),
                  this,
                  this,
                  this,
                  this),
                  ......

在WebContentsImpl的创建中主要会创建一个controller_和frame_tree_

cotroller_的创建过程

NavigationControllerImpl::NavigationControllerImpl(
    NavigationControllerDelegate* delegate,
    BrowserContext* browser_context)
    : browser_context_(browser_context),
      pending_entry_(nullptr),
      failed_pending_entry_id_(0),
      last_committed_entry_index_(-1),
      pending_entry_index_(-1),
      transient_entry_index_(-1),
      delegate_(delegate),
      ssl_manager_(this),
      needs_reload_(false),
      is_initial_navigation_(true),
      in_navigate_to_pending_entry_(false),
      pending_reload_(ReloadType::NONE),
      get_timestamp_callback_(base::Bind(&base::Time::Now)),
      last_committed_reload_type_(ReloadType::NONE) {
  DCHECK(browser_context_);
}

这个controller_是NavigationControllerImpl的一个实例,NavigationControllerImpl是继承NavigationController,它包含了LoadUrl,CanGoBack等方法,这个类的作用在我们研究webview加载页面的过程中会又更深入的研究。在这里只是创建了一个NavigationControllerImpl对象,为其中的browser_context_和delegate_进行赋值,这里的delegate_就是WebContentsImpl对象

frame_tree_的创建过程

在创建frame_tree_之前会先构建NavigatorImpl对象。

NavigatorImpl::NavigatorImpl(NavigationControllerImpl* navigation_controller,
                             NavigatorDelegate* delegate)
    : controller_(navigation_controller), delegate_(delegate) {}

NavigatorImpl主要把之前创建的NavigationControllerImpl对象放到自己的controller_中和之前的WebContentsImpl(也就是这里的NavigatorDelegate)对象放到delegate_中,以便后续使用。接下来看下frame_tree_的实现

FrameTree::FrameTree(Navigator* navigator,
                     RenderFrameHostDelegate* render_frame_delegate,
                     RenderViewHostDelegate* render_view_delegate,
                     RenderWidgetHostDelegate* render_widget_delegate,
                     RenderFrameHostManager::Delegate* manager_delegate)
    : render_frame_delegate_(render_frame_delegate),
      render_view_delegate_(render_view_delegate),
      render_widget_delegate_(render_widget_delegate),
      manager_delegate_(manager_delegate),
      root_(new FrameTreeNode(this,
                              navigator,
                              nullptr,
                              // The top-level frame must always be in a
                              // document scope.
                              blink::WebTreeScopeType::kDocument,
                              std::string(),
                              std::string(),
                              false,
                              base::UnguessableToken::Create(),
                              FrameOwnerProperties(),
                              blink::FrameOwnerElementType::kNone)),
      focused_frame_tree_node_id_(FrameTreeNode::kFrameTreeNodeInvalidId),
      load_progress_(0.0) {}

这里先将FrameTree需要的一些变量进行赋值,注意这里的RenderFrameHostDelegate,RenderViewHostDelegate,RenderWidgetHostDelegate和RenderFrameHostManager::Delegate对像都是同一个WebContentsImpl对象,为这些变量赋完值之后会创建FrameTree的根节点root_,节点类型是FrameTreeNode,下面看下FrameTreeNode的实现

FrameTreeNode::FrameTreeNode(FrameTree* frame_tree,
                             Navigator* navigator,
                             FrameTreeNode* parent,
                             blink::WebTreeScopeType scope,
                             const std::string& name,
                             const std::string& unique_name,
                             bool is_created_by_script,
                             const base::UnguessableToken& devtools_frame_token,
                             const FrameOwnerProperties& frame_owner_properties,
                             blink::FrameOwnerElementType owner_type)
    : frame_tree_(frame_tree),
      navigator_(navigator),
      render_manager_(this, frame_tree->manager_delegate()),
      frame_tree_node_id_(next_frame_tree_node_id_++),
      parent_(parent),
      depth_(parent ? parent->depth_ + 1 : 0u),
      opener_(nullptr),
      original_opener_(nullptr),
      has_committed_real_load_(false),
      is_collapsed_(false),
      ......

FrameTreeNode的创建过程主要也是为一些变量的赋值,比如frame_tree_,navigator等,同时会为这个节点创建一个manager,也就是这里的render_manager_,他是一个RenderFrameHostManager对象

RenderFrameHostManager::RenderFrameHostManager(FrameTreeNode* frame_tree_node,
                                               Delegate* delegate)
    : frame_tree_node_(frame_tree_node),
      delegate_(delegate),
      weak_factory_(this) {
  DCHECK(frame_tree_node_);
}

RenderFrameHostManager对象在初始化时会将对应的FrameTree节点和Delegate对象保存下来,这里的delegate还是之前创建的WebContentsImpl对象。这里FrameTree中每个节点都会有一个render_manager_。

这样整个FrameTree就创建完了,里面包含了一个跟节点root_

调用WebContentsImpl的Init方法

FrameTree创建完成之后我们看下WebContentsImpl的Init方法的实现

void WebContentsImpl::Init(const WebContents::CreateParams& params) {
  // This is set before initializing the render manager since
  // RenderFrameHostManager::Init calls back into us via its delegate to ask if
  // it should be hidden.
  visibility_ =
      params.initially_hidden ? Visibility::HIDDEN : Visibility::VISIBLE;

  if (!params.last_active_time.is_null())
    last_active_time_ = params.last_active_time;

  scoped_refptr<SiteInstance> site_instance = params.site_instance;
  if (!site_instance)

    //1.创建SiteInstance
    site_instance = SiteInstance::Create(params.browser_context);
  if (params.desired_renderer_state == CreateParams::kNoRendererProcess) {
    static_cast<SiteInstanceImpl*>(site_instance.get())
        ->PreventAssociationWithSpareProcess();
  }

  //2.创建各个id
  int32_t view_routing_id = params.routing_id;
  int32_t main_frame_widget_routing_id = params.main_frame_widget_routing_id;
  if (main_frame_widget_routing_id == MSG_ROUTING_NONE) {
    view_routing_id = site_instance->GetProcess()->GetNextRoutingID();
    main_frame_widget_routing_id =
        site_instance->GetProcess()->GetNextRoutingID();
  }

  DCHECK_NE(view_routing_id, main_frame_widget_routing_id);

  //Init
  GetRenderManager()->Init(
      site_instance.get(), view_routing_id, params.main_frame_routing_id,
      main_frame_widget_routing_id, params.renderer_initiated_creation);

  // blink::FrameTree::setName always keeps |unique_name| empty in case of a
  // main frame - let's do the same thing here.
  std::string unique_name;
  frame_tree_.root()->SetFrameName(params.main_frame_name, unique_name);

  WebContentsViewDelegate* delegate =
      GetContentClient()->browser()->GetWebContentsViewDelegate(this);

  if (GuestMode::IsCrossProcessFrameGuest(this)) {
    view_.reset(new WebContentsViewChildFrame(
        this, delegate, &render_view_host_delegate_view_));
  } else {
    //4.创建WebContentsView
    view_.reset(CreateWebContentsView(this, delegate,
                                      &render_view_host_delegate_view_));
    if (browser_plugin_guest_) {
      view_ = std::make_unique<WebContentsViewGuest>(
          this, browser_plugin_guest_.get(), std::move(view_),
          &render_view_host_delegate_view_);
    }
  }
  CHECK(render_view_host_delegate_view_);
  CHECK(view_.get());

  gfx::Size initial_size = params.initial_size;

  
  view_->CreateView(initial_size, params.context);

#if BUILDFLAG(ENABLE_PLUGINS)
  plugin_content_origin_whitelist_.reset(
      new PluginContentOriginWhitelist(this));
#endif

  registrar_.Add(this,
                 NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
                 NotificationService::AllBrowserContextsAndSources());

  screen_orientation_provider_.reset(new ScreenOrientationProvider(this));

  manifest_manager_host_.reset(new ManifestManagerHost(this));

#if defined(OS_ANDROID)
  date_time_chooser_.reset(new DateTimeChooserAndroid());
#endif

  // BrowserPluginGuest::Init needs to be called after this WebContents has
  // a RenderWidgetHostViewGuest. That is, |view_->CreateView| above.
  if (browser_plugin_guest_)
    browser_plugin_guest_->Init();

  for (size_t i = 0; i < g_created_callbacks.Get().size(); i++)
    g_created_callbacks.Get().at(i).Run(this);

  // If the WebContents creation was renderer-initiated, it means that the
  // corresponding RenderView and main RenderFrame have already been created.
  // Ensure observers are notified about this.
  if (params.renderer_initiated_creation) {
    GetRenderViewHost()->GetWidget()->set_renderer_initialized(true);
    GetRenderViewHost()->DispatchRenderViewCreated();
    GetRenderManager()->current_frame_host()->SetRenderFrameCreated(true);
  }


  
  // Create the renderer process in advance if requested.
  if (params.desired_renderer_state ==
      CreateParams::kInitializeAndWarmupRendererProcess) {
    if (!GetRenderManager()->current_frame_host()->IsRenderFrameLive()) {
      GetRenderManager()->InitRenderView(GetRenderViewHost(), nullptr);
    }
  }

  // Ensure that observers are notified of the creation of this WebContents's
  // main RenderFrameHost. It must be done here for main frames, since the
  // NotifySwappedFromRenderManager expects view_ to already be created and that
  // happens after RenderFrameHostManager::Init.
  NotifySwappedFromRenderManager(
      nullptr, GetRenderManager()->current_frame_host(), true);
}

这个Init方法的代码比较长,我们分几个部分来研究下

1.创建SiteInstance

由于WebContentsImpl创建的时候params里的site_instance是空的,所以这里会先调用SiteInstance的Create方法来创建一个SiteInstance,这里的逻辑比较简单,就是创建几个相关的对象,下面是这里涉及到的一些代码

scoped_refptr<SiteInstance> SiteInstance::Create(
    BrowserContext* browser_context) {
  DCHECK(browser_context);
  return SiteInstanceImpl::Create(browser_context);
}
scoped_refptr<SiteInstanceImpl> SiteInstanceImpl::Create(
    BrowserContext* browser_context) {
  DCHECK(browser_context);
  return base::WrapRefCounted(
      new SiteInstanceImpl(new BrowsingInstance(browser_context)));
}

2.创建各个id

这一步主要是为main_frame_widget_routing_id等一些变量赋值

3.GetRenderManager->Init分析

先看下GetRenderManager这个方法的实现

RenderFrameHostManager* WebContentsImpl::GetRenderManager() const {
  return frame_tree_.root()->render_manager();
}

它返回的是一个RenderFrameHostManager对象,这个对象是在前面创建根节点FrameTreeNode的时候创建的,这个manager对象是用来管理FrameTree的根节点的。

下面再看下RenderFrameHostManager的Init方法

void RenderFrameHostManager::Init(SiteInstance* site_instance,
                                  int32_t view_routing_id,
                                  int32_t frame_routing_id,
                                  int32_t widget_routing_id,
                                  bool renderer_initiated_creation) {
  DCHECK(site_instance);
  SetRenderFrameHost(CreateRenderFrameHost(site_instance, view_routing_id,
                                           frame_routing_id, widget_routing_id,
                                           delegate_->IsHidden(),
                                           renderer_initiated_creation));

  // Notify the delegate of the creation of the current RenderFrameHost.
  // Do this only for subframes, as the main frame case is taken care of by
  // WebContentsImpl::Init.
  if (!frame_tree_node_->IsMainFrame()) {
    delegate_->NotifySwappedFromRenderManager(
        nullptr, render_frame_host_.get(), false);
  }
}

这里的主要逻辑是调用CreateRenderFrameHost来创建一个RenderFrameHost对象,然后设置给本地变量,我们接下来看下CreateRenderFrameHost的实现

std::unique_ptr<RenderFrameHostImpl>
RenderFrameHostManager::CreateRenderFrameHost(
    SiteInstance* site_instance,
    int32_t view_routing_id,
    int32_t frame_routing_id,
    int32_t widget_routing_id,
    bool hidden,
    bool renderer_initiated_creation) {
  if (frame_routing_id == MSG_ROUTING_NONE)
    frame_routing_id = site_instance->GetProcess()->GetNextRoutingID();

  // Create a RVH for main frames, or find the existing one for subframes.
  FrameTree* frame_tree = frame_tree_node_->frame_tree();
  RenderViewHostImpl* render_view_host = nullptr;

  //1.判断是不是MainFrame
  if (frame_tree_node_->IsMainFrame()) {

    //2.创建RenderViewHost
    render_view_host = frame_tree->CreateRenderViewHost(
        site_instance, view_routing_id, frame_routing_id, widget_routing_id,
        false, hidden);
    // TODO(avi): It's a bit bizarre that this logic lives here instead of in
    // CreateRenderFrame(). It turns out that FrameTree::CreateRenderViewHost
    // doesn't /always/ create a new RenderViewHost. It first tries to find an
    // already existing one to reuse by a SiteInstance lookup. If it finds one,
    // then the supplied routing IDs are completely ignored.
    // CreateRenderFrame() could do this lookup too, but it seems redundant to
    // do this lookup in two places. This is a good yak shave to clean up, or,
    // if just ignored, should be an easy cleanup once RenderViewHostImpl has-a
    // RenderWidgetHostImpl. https://crbug.com/545684
    if (view_routing_id == MSG_ROUTING_NONE) {
      widget_routing_id = render_view_host->GetWidget()->GetRoutingID();
    } else {
      DCHECK_NE(view_routing_id, widget_routing_id);
      DCHECK_EQ(view_routing_id, render_view_host->GetRoutingID());
    }
  } else {
    render_view_host = frame_tree->GetRenderViewHost(site_instance);
    CHECK(render_view_host);
  }

  //3.RenderFrameHostFactory::Create方法
  return RenderFrameHostFactory::Create(
      site_instance, render_view_host, frame_tree->render_frame_delegate(),
      frame_tree, frame_tree_node_, frame_routing_id, widget_routing_id, hidden,
      renderer_initiated_creation);
}

我们把RenderFrameHostImpl的创建过程分为3个部分来讲解

a.判断是不是MainFrame

判断是不是MainFrame的逻辑为

bool FrameTreeNode::IsMainFrame() const {
  return frame_tree_->root() == this;
}

由于这里的frame_tree_node_对应的是该RenderFrameHostManager中的FrameTree的一个节点,而该RenderFrameHostManager对象就是前面通过FrameTree的根节点root_得到的,所以这里的IsMainFrame为true。顺便说下每个webview都有一个MainFrame,用来承载网页内容,如果网页中有嵌入iframe标签的话会再创建一个FrameTreeNode,该node对应的Frame为SubFrame,即不是MainFrame。

b.创建RenderViewHost

下面我们看下CreateRenderViewHost的实现逻辑

RenderViewHostImpl* FrameTree::CreateRenderViewHost(
    SiteInstance* site_instance,
    int32_t routing_id,
    int32_t main_frame_routing_id,
    int32_t widget_routing_id,
    bool swapped_out,
    bool hidden) {
  if (RenderViewHostImpl* existing_rvh = GetRenderViewHost(site_instance))
    return existing_rvh;

  RenderViewHostImpl* rvh =
      static_cast<RenderViewHostImpl*>(RenderViewHostFactory::Create(
          site_instance, render_view_delegate_, render_widget_delegate_,
          routing_id, main_frame_routing_id, widget_routing_id, swapped_out,
          hidden));

  render_view_host_map_[site_instance->GetId()] = base::WrapUnique(rvh);
  return rvh;
}

这里主要通过RenderViewHostFactory::Create方法创建一个RenderViewHostImpl对象,然后将这个对象放在render_view_host_map_的map中,以便后续可以直接使用。下面看下RenderViewHostFactory::Create的实现

// static
RenderViewHost* RenderViewHostFactory::Create(
    SiteInstance* instance,
    RenderViewHostDelegate* delegate,
    RenderWidgetHostDelegate* widget_delegate,
    int32_t routing_id,
    int32_t main_frame_routing_id,
    int32_t widget_routing_id,
    bool swapped_out,
    bool hidden) {
  // RenderViewHost creation can be either browser-driven (by the user opening a
  // new tab) or renderer-driven (by script calling window.open, etc).
  //
  // In the browser-driven case, the routing ID of the view is lazily assigned:
  // this is signified by passing MSG_ROUTING_NONE for |routing_id|.
  if (routing_id == MSG_ROUTING_NONE) {
    DCHECK_EQ(widget_routing_id, MSG_ROUTING_NONE);
    routing_id = instance->GetProcess()->GetNextRoutingID();
    widget_routing_id = instance->GetProcess()->GetNextRoutingID();
  } else {
    // Otherwise, in the renderer-driven case, the routing ID of the view is
    // already set. This is due to the fact that a sync render->browser IPC is
    // involved. In order to quickly reply to the sync IPC, the routing IDs are
    // assigned as early as possible. The IO thread immediately sends a reply to
    // the sync IPC, while deferring the creation of the actual Host objects to
    // the UI thread.
  }
  if (factory_) {
    return factory_->CreateRenderViewHost(instance, delegate, widget_delegate,
                                          routing_id, main_frame_routing_id,
                                          widget_routing_id, swapped_out);
  }
  return new RenderViewHostImpl(
      instance,
      base::WrapUnique(RenderWidgetHostFactory::Create(
          widget_delegate, instance->GetProcess(), widget_routing_id, nullptr,
          hidden)),
      delegate, routing_id, main_frame_routing_id, swapped_out,
      true /* has_initialized_audio_host */);
}

这里主要是调用RenderViewHostImpl的构造方法创建一个RenderViewHostImpl对象,由于RenderViewHostImpl的创建过程比较复杂,涉及到Render进程的启动等逻辑,这块我们在后面再分析。

回到前面CreateRenderFrameHost的逻辑中,在创建完RenderViewHostImpl之后会调用RenderFrameHostFactory的Create方法

c.RenderFrameHostFactory::Create

std::unique_ptr<RenderFrameHostImpl> RenderFrameHostFactory::Create(
    SiteInstance* site_instance,
    RenderViewHostImpl* render_view_host,
    RenderFrameHostDelegate* delegate,
    FrameTree* frame_tree,
    FrameTreeNode* frame_tree_node,
    int32_t routing_id,
    int32_t widget_routing_id,
    bool hidden,
    bool renderer_initiated_creation) {
  if (factory_) {
    return factory_->CreateRenderFrameHost(
        site_instance, render_view_host, delegate, frame_tree, frame_tree_node,
        routing_id, widget_routing_id, hidden, renderer_initiated_creation);
  }
  return base::WrapUnique(new RenderFrameHostImpl(
      site_instance, render_view_host, delegate, frame_tree, frame_tree_node,
      routing_id, widget_routing_id, hidden, renderer_initiated_creation));
}

这里主要也是通过RenderFrameHostImpl来构建一个RenderFrameHost对象,把之前创建的RenderViewHostImpl对象存贮在自己变量中。

接下来再回到WebContentsImpl的Init中来

4.创建WebContentsView

WebContentsView* CreateWebContentsView(
    WebContentsImpl* web_contents,
    WebContentsViewDelegate* delegate,
    RenderViewHostDelegateView** render_view_host_delegate_view) {
  WebContentsViewAndroid* rv = new WebContentsViewAndroid(
      web_contents, delegate);
  *render_view_host_delegate_view = rv;
  return rv;
}

在android平台会创建一个WebContentsViewAndroid

这样整个WebContentsImpl的Init方法基本就介绍完了。

再回到JNI_AwContents_Init中,即

static jlong JNI_AwContents_Init(JNIEnv* env,
                                 const JavaParamRef<jobject>& browser_context) {
  // TODO(joth): Use |browser_context| to get the native BrowserContext, rather
  // than hard-code the default instance lookup here.
  std::unique_ptr<WebContents> web_contents(content::WebContents::Create(
      content::WebContents::CreateParams(AwBrowserContext::GetDefault())));
  // Return an 'uninitialized' instance; most work is deferred until the
  // subsequent SetJavaPeers() call.
  return reinterpret_cast<intptr_t>(new AwContents(std::move(web_contents)));
}

在创建完WebContentsImpl之后会创建AwContents对象。

AwContents::AwContents(std::unique_ptr<WebContents> web_contents)
    : content::WebContentsObserver(web_contents.get()),
      browser_view_renderer_(
          this,
          base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})),
      web_contents_(std::move(web_contents)) {
  base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, 1);
  icon_helper_.reset(new IconHelper(web_contents_.get()));
  icon_helper_->SetListener(this);
  web_contents_->SetUserData(android_webview::kAwContentsUserDataKey,
                             std::make_unique<AwContentsUserData>(this));
  browser_view_renderer_.RegisterWithWebContents(web_contents_.get());

  CompositorID compositor_id;
  if (web_contents_->GetRenderViewHost() &&
      web_contents_->GetRenderViewHost()->GetProcess()) {
    compositor_id.process_id =
        web_contents_->GetRenderViewHost()->GetProcess()->GetID();
    compositor_id.routing_id =
        web_contents_->GetRenderViewHost()->GetWidget()->GetRoutingID();
  }

  browser_view_renderer_.SetActiveCompositorID(compositor_id);
  render_view_host_ext_.reset(
      new AwRenderViewHostExt(this, web_contents_.get()));

  permission_request_handler_.reset(
      new PermissionRequestHandler(this, web_contents_.get()));

  AwAutofillClient* autofill_manager_delegate =
      AwAutofillClient::FromWebContents(web_contents_.get());
  if (autofill_manager_delegate)
    InitAutofillIfNecessary(autofill_manager_delegate->GetSaveFormData());
  content::SynchronousCompositor::SetClientForWebContents(
      web_contents_.get(), &browser_view_renderer_);
  AwContentsLifecycleNotifier::OnWebViewCreated();
}

这里主要是创建browser_view_renderer_,它是一个BrowserViewRenderer对象

BrowserViewRenderer::BrowserViewRenderer(
    BrowserViewRendererClient* client,
    const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner)
    : client_(client),
      ui_task_runner_(ui_task_runner),
      current_compositor_frame_consumer_(nullptr),
      compositor_(nullptr),
      is_paused_(false),
      view_visible_(false),
      window_visible_(false),
      attached_to_window_(false),
      was_attached_(false),
      hardware_enabled_(false),
      dip_scale_(0.f),
      page_scale_factor_(1.f),
      min_page_scale_factor_(0.f),
      max_page_scale_factor_(0.f),
      on_new_picture_enable_(false),
      clear_view_(false),
      offscreen_pre_raster_(false),
      weak_ptr_factory_(this) {}

这里的client就是前面AwContents对象。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值