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對象本身。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章