QT:CEF實現js函數與C++函數的異步調用


1.CEF3使用多進程模式,Browser與Render分別處於兩個獨立進程之中;一般而言,Browser進程與我們的窗口進程一致,Render進程是一個獨立的進程。

2.Browser進程和Render進程都包含browser和frame對象;

3.在CEF提供的例子中,主要是通過繼承CefV8Handler,實現其

bool CefV8HandlerEx::Execute(const CefString &name,
                             CefRefPtr<CefV8Value> object,
                             const CefV8ValueList &arguments,
                             CefRefPtr<CefV8Value> &retval,
                             CefString &exception)

方法來實現js對C++函數的調用。

如果這個函數調用是一個簡單的調用,即當函數調用發生時,如果我們能夠快速的返回結果,那么我們可以通過更改retval的值來返回函數調用結果。

因為這個函數調用是發生在Render進程中的,如果函數調用時,我們想獲取Browser進程內的信息,那我們就需要通過進程間通訊(方式:調用Frame的SendProcessMessage(PID_Browser,msg))告訴Browser進程,但是此時的問題就是,進程間通訊是個異步操作,我們無法通過這個方式獲得結果,所以會導致整個調用不再是連續的,因此js函數調用的結果將不可知,那該如何解決?

我們可以借助於js的異步調用來完成這一點,具體的思路如下:

1.js發起函數調用Func(需要注意這個Func是需要在Render_App的OnContextCreated方法中綁定到Context上,具體可參考https://bitbucket.org/chromiumembedded/cef/wiki/JavaScriptIntegration.md#markdown-header-window-binding,且有一個CefV8Handler與Func綁定),這個Func傳遞一個回調函數(callback)作為參數;

2.Render進程中的CefV8Handler的Execute檢測到該函數,取得callback參數,將其放入到函數調用緩存中,可以參考https://bitbucket.org/chromiumembedded/cef/wiki/GeneralUsage.md#markdown-header-asynchronous-javascript-bindings

3.發送一個進程間消息告訴Browser進程,Browser進程需要實現OnProcessMessageReceived方法。Browser接受到該消息以后,完成相應的操作,並發送一個進程間消息告訴Render進程,Render進程同樣也需要實現OnProcessMessageReceived方法;

4.Render進程接受到特定消息以后,檢索出message中包含的參數信息,並從函數調用緩存中查找特定的callback函數;

5.當從在對應的callback時,調用該callback

6.js在Func中傳遞的callback中接收參數信息,並完成后續工作。

 

需要注意的是:

1.這個RenderApp進程,如果在加載的page中存在多個iframe,則這個OnContextCreated會被調用多次,如果不想再每個iframe中注冊這個Func函數,則將其寫入OnWebKitInitialed中,這個也是Render的一個接口。

2.如果存在多個iframe,並不在同一個域,則有可能會出現有些iframe無法接收消息的情況;

3.CefV8Handler最好實在RenderAPP的構造中初始化一次,不然在存在多個iframe的情況下,可能會出現函數緩存為空的情況,具體原因未知。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM