首页 > 代码库 > 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对象本身。