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