chromium WebUI实例

前面介绍了chromium中WebUI机制的几个主要的组件,这篇文章,用一个功能来看看WebUI是怎么使用的。

本实例的背景:显示一个自定义的设置界面,包括对历史记录、书签、cookies等一系列用户数据的操作,现在我使用其中的一个功能来介绍一下大致的实现。


首先,我们要创建几个类:

        HistoryUI:继承自WebUI中的controller;在这个类中,我们还创建了一个WebUIDataSourceImpl类的实例,主要用来提供数据;

        webui对象,这个对象是在加载本地页面时由webcontents创建好的;

        HistoryService,这个类是一个执行类,主要作用是来维护一个线程,用来执行我们指定的操作,这个类是我自己定义的,使用时可以自己指定其他的类;

        HistoryBackend,这个类也是自己定义的,其中定义了我们在这个本地页面中要执行的操作。

现在我们来看这个过程:

在HistoryUI中:

HistoryUI::HistoryUI(){
    ...

    web_ui->RegisterMessageCallback("deleteHistoryItemByDate", base::Bind(&HistoryUI::HandleDeleteHistoryItemByDate, base::Unretained(this)));
    ...
 }

void HistoryUI::HandleDeleteHistoryItemByDate(const base::ListValue* arg) {
    base::string16 key, id, date;
    args->GetString(0, &key);
    args->GetString(1, &id);
    args->GetString(2, &date);

    HistoryService* hs = HistoryService::GetInstance();
    hs->DeleteItemByDate(date, 
        base::Bind(&HistoryUI::CallJavaScriptFunctionWith2Args, base::Unretained(this), 
        base::StringValue(key), base::StringValue(id)));
}

上面的两个函数:

        第一在构造函数中,发挥了WebUI类的功能,"deleteHistoryItemByDate"就是页面调到js代码,由js代码传递过来的参数的第一个值。

        如上一篇文章提到的,js产生调用之后,通过V8引擎将参数传递到render进程,然后render进程通过IPC消息将这个参数传递到browser进程,这个IPC消息就是被此处的webui对象所处理,解析出其携带的参数,然后调用已经注册的回调函数。

        第二个函数,这个函数就是注册到webui中的js直接调用回调函数,但我们此时看到在这个函数中,我们又一次绑定了一个回调函数:CallJavaScriptFunctionWith2Args,这个函数的实质就是调用了webui中的方法来调用js代码,附带了两个参数。以上这两点就体现出了webui的作用,就是将js调用c++以及c++执行js联系起来。


继续来看代码:

在HistoryBackend中:

void HistoryBackend::DeleteItemByDate(const base::string16& date, base::Callback<void()> callback) {
    if (HistoryDataBase::GetInstance()->DeleteItemByDate(base::UTF16ToUTF8(date))) {
        ...
    }
    
    callback.Run();
}
以上这个HistoryBackend中定义的具体的实现方法,也就是js调用下来之后,实现具体功能的函数。我现在分析的功能就是按时间来删除条目。在具体的操作正确结束之后,执行了第二个参数callback,这个就是在HistoryUI中注册的调用js代码的方法,用来执行在功能完成后,向js发出响应。


继续看代码:

void HistoryService::DeleteItemByDate(const base::string16& date, base::Callback<voiid()> callback) {
    service_backend_->scheduleTask(base::Bind(&HistoryBackend::DeleteItemByDate, history_backend, date, callback));
}

从以上的代码中可以看到一个schedultTask的函数,它的目的就是维持一个线程,把Bind的函数一个个放进线程里面去执行。此处,callback就是来自于在HistoryUI中注册的CallJavaScriptFunctionWith2Arg()。而次数又继续绑定了函数,那就是HistoryBackend的DeleteItemByDate函数,最终运行就是HistoryBackend::DeleteItemByDate.


在以上的代码中,后两个类都是自己实现的,在具体做的时候,需要根据具体的情况来定义自己的函数。

关于以上类以及函数的调用关系需要捋一捋,Callback顾名思义,就是一个回调函数,此处理解为闭包貌似好一点,因为在callback中包含了函数地址以及函数参数,其实就相当于是打包了一个函数要运行的一个环境。


在WebUI过程中,还有一个部分,那就是资源文件的编译、使用,放在下一篇文章再详细介绍chromium里面对本地资源的处理方法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值