首页 > 代码库 > Chromium中网页加载进度条研究

Chromium中网页加载进度条研究

1.     Shell.java中有成员变量:mProgressDrawable。

该成员变量在方法:onFinishInflate中被初始化。

在该类中有方法:onLoadProgressChanged,该方法中对进度条的值进行改变,并且对刷新完成事件进行反馈。

2.     上面的这个方法是在cc文件中被调用的。

上面方法对应的cc方法是shell_android.cc文件中的LoadProgressChanged方法。

voidShell::LoadProgressChanged(WebContents* source, double progress) {

  JNIEnv* env = AttachCurrentThread();

  Java_Shell_onLoadProgressChanged(env,java_object_.obj(), progress);

}

3.     我们看看shell.h文件。

classShell : public WebContentsDelegate,

所以,shell是WebContentDelegate的子类。

4.     在web_contents_impl.cc文件中,有方法:

DidChangeLoadProgress

  voidWebContentsImpl::DidChangeLoadProgress(double progress) {

      if(delegate_)

          delegate_->LoadProgressChanged(this,progress);

}

这里的delegate是WebContentsDelegate类型,会调用shell类中的方法。

5.     上面的参量delegate_是在同文件方法WebContentsImpl::SetDelegate中赋值。

WebContentsImpl::SetDelegate方法,会在shell.cc文件中的CreateShell方法中调用。

6.     接着我们看看WebContentsImpl::DidChangeLoadProgress是在哪里调用的。

现在我们从另一个方向看看网页加载进度条的改变。

7.     文件render_view_impl.cc中didChangeLoadProgress方法。

   voidRenderViewImpl::didChangeLoadProgress(WebFrame* frame,

                                          double load_progress) {

  if (load_progress_tracker_ !=NULL)

    load_progress_tracker_->DidChangeLoadProgress(frame,load_progress);

}

  此方法调用是文件load_progress_tracker.cc种方法:

  DidChangeLoadProgress,该方法中又会调动同文件中

  SendChangeLoadProgress

  上面方法实现如下:

   voidLoadProgressTracker::SendChangeLoadProgress() {

   last_time_progress_sent_ =base::TimeTicks::Now();

     render_view_->Send(

       newViewHostMsg_DidChangeLoadProgress(render_view_->routing_id(),

                                           progress_));

}

8.     上面的消息处理是在文件:render_view_host_impl.cc中。在方法OnMessageReceived中有:

IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeLoadProgress,                       OnDidChangeLoadProgress)

  处理这个消息。

  实际的处理方法是同文件中的方法:

 void RenderViewHostImpl::OnDidChangeLoadProgress(double load_progress){

  delegate_->DidChangeLoadProgress(load_progress);

}

  而上面这个delegate_是RenderViewHostDelegate类型。

  现在问题的关键是找找RenderViewHostImpl是在哪里创建的,这是解决问题的关键。

  然后这个delegate_在创建RenderViewHostImpl对象的时候,如何赋值的,关键!

9.     上面提到delegate_是RenderViewHostDelegate类型。

而 在文件web_contents_impl.h文件中可以看到:

class CONTENT_EXPORT WebContentsImpl
    : public NON_EXPORTED_BASE(WebContents),
      public NON_EXPORTED_BASE(RenderFrameHostDelegate),
      public RenderViewHostDelegate,
      public RenderWidgetHostDelegate,
      public RenderFrameHostManager::Delegate,
      public NotificationObserver,
      public NON_EXPORTED_BASE(NavigationControllerDelegate),
      public NON_EXPORTED_BASE(NavigatorDelegate) {

所以,webcontentsimpl对象就是renderviewhostdelegate类型。

10.  这样就能对起来了。但是,我还想看看webcontentsimpl对象是怎么传到RenderViewHostImpl中的。

11.   从render_view_host_impl.cc文件的构造函数中delegate_(delegate),看,这个参数是调用该文件的构造函数的时候被赋值。

参看文档27.render_view_host_impl.cc的创建文档。我们知道,这个对象是在render_view_host_factory.cc文件中的RenderViewHostFactory::Create方法中的:

if (factory_) {

    returnfactory_->CreateRenderViewHost(instance, delegate, widget_delegate,  routing_id, main_frame_routing_id,  swapped_out);                             

  调用。

12.  而上面这个方法又在:frame_tree.cc文件中的:

FrameTree::CreateRenderViewHostForMainFrame方法中的

    RenderViewHostImpl* rvh =static_cast<RenderViewHostImpl*>(

      RenderViewHostFactory::Create(site_instance,

                                   render_view_delegate_,

                                   render_widget_delegate_,

                                   routing_id,

                                   main_frame_routing_id,

                                   swapped_out,

                                   hidden));

    调用,参量render_view_delegate_是在构造函数的FrameTree::FrameTree中被赋值。

13.  我们继续看看这个构造函数在哪里被调用。

在web_contents_impl.cc文件中,构造函数中:

      frame_tree_(newNavigatorImpl(&controller_, this),

                  this, this, this, this),

   这里创建了frame_tree.cc对象。通过这里看到,frame_tree.cc文件的成员变量render_view_delegate_就是web_contents_impl对象本身。