chromium - post task for web-ui
阿新 • • 發佈:2018-12-20
前言
web-ui和js互動,為了避免阻塞web-ui的訊息迴圈,不能直接PostTask或直接bind來幹活,需要用和UI相關的BrowserThread::PostTask.
通過實驗可知,即使用BrowserThread::PostTask,發起的任務很頻繁時,web-ui也卡的很。
查了chromium工程中的已有實現,看看BrowserThread都怎麼用。發現人家都是用BrowserThread::PostDelayedTask,我也用BrowserThread::PostDelayedTask來發起任務,在任務指定的本類屬回撥中,再用BrowserThread::PostDelayedTask發起下一個任務。這時,web-ui很流暢,一點都不卡。
實驗
BrowserThread::PostDelayedTask的用法例子
web-ui中程式碼很少,只有初始化的程式碼。
幹活都時繫結一個WebUIMessageHandler子類來幹活。
// Class acting as a controller of the chrome://download-internals WebUI. class DownloadInternalsUIMessageHandler : public content::WebUIMessageHandler, public download::Logger::Observer { public: DownloadInternalsUIMessageHandler(); ~DownloadInternalsUIMessageHandler() override; // content::WebUIMessageHandler implementation. void RegisterMessages() override;
在WebUIMessageHandler子類中,找一個只有初始化時才執行的成員函式,PostDelayedTask即可。PostDelayedTask非常適合在訊息迴圈中繫結自己類的成員函式來幹活。
void DownloadInternalsUIMessageHandler::HandleGetServiceStatus( const base::ListValue* args) { AllowJavascript(); const base::Value* callback_id; CHECK(args->Get(0, &callback_id)); ResolveJavascriptCallback(*callback_id, download_service_->GetLogger()->GetServiceStatus()); // 這裡是服務下載有效, 啟動一次本web-ui, 這裡只進入一次,很適合自動啟動任務 post_ui_task_for_download(); } void DownloadInternalsUIMessageHandler::post_ui_task_for_download() { // http://192.168.2.222/a.txt // 可以用http下載的測試檔案 m_str_url_by_js_first = "http://192.168.2.222/a.txt"; BrowserThread::PostDelayedTask( BrowserThread::UI, FROM_HERE, base::BindOnce(&DownloadInternalsUIMessageHandler::HandleStartDownload_url_again, base::Unretained(this)), base::TimeDelta::FromSeconds(2)); // 延時是以秒為單位的, 都是約數設定10秒延時,有時7秒發起任務,有時11秒發起任務 }
void DownloadInternalsUIMessageHandler::HandleStartDownload_url_again()
{
if (!m_str_url_by_js_first.empty()) {
GURL url_now = GURL(m_str_url_by_js_first);
HandleStartDownload_url(url_now);
}
}
void DownloadInternalsUIMessageHandler::HandleStartDownload_url(GURL& url)
{
if (!url.is_valid()) {
LOG(WARNING) << "Can't parse download URL, try to enter a valid URL.";
return;
}
download::DownloadParams params;
params.guid = base::GenerateGUID();
params.client = download::DownloadClient::DEBUGGING;
params.request_params.method = "GET";
params.request_params.url = url;
net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("download_internals_webui_source", R"(
semantics {
sender: "Download Internals Page"
description:
"Starts a download with background download service in WebUI."
trigger:
"User clicks on the download button in "
"chrome://download-internals."
data: "None"
destination: WEBSITE
}
policy {
cookies_allowed: YES
cookies_store: "user"
setting: "This feature cannot be disabled by settings."
policy_exception_justification: "Not implemented."
})");
params.traffic_annotation =
net::MutableNetworkTrafficAnnotationTag(traffic_annotation);
DCHECK(download_service_);
download_service_->StartDownload(params);
}