詳解MeeGo Touch服務(wù)框架
諾基亞宣稱MeeGo比Android更具開放性:MeeGo基于Linux的平臺(tái)、可以驅(qū)動(dòng)多種計(jì)算設(shè)備,包括手機(jī)、上網(wǎng)本、平板電腦、連接電視和車載信息娛樂系統(tǒng)。事實(shí)真的是如此嗎?我們先了解一下MeeGo Touch服務(wù)框架。
51CTO推薦專題:MeeGo:無(wú)所不在的移動(dòng)操作系統(tǒng)
戶進(jìn)程接口被稱這個(gè)服務(wù)框架是這樣的一種IPC機(jī)制,這個(gè)機(jī)制允許應(yīng)用單元簡(jiǎn)便地使用或者服務(wù)于一個(gè)接口。在這個(gè)文檔,用為“使用者”,而提供者進(jìn)程接口被稱為“提供者”。
這個(gè)服務(wù)框架的目的如下:
◆提供一個(gè)可簡(jiǎn)單使用的IPC機(jī)制
◆確保在服務(wù)的使用者和提供者之間沒有運(yùn)行時(shí)二進(jìn)制依賴關(guān)系
◆允許用戶在使用一個(gè)接口時(shí)不用擔(dān)心選擇或者連接到一個(gè)接口時(shí)的具體邏輯
◆允許用戶能查詢提供者的列表,并且能從中選擇一個(gè)
基本的服務(wù)機(jī)制
下圖展示了當(dāng)一個(gè)服務(wù)端的用戶(SU)使用一個(gè)接口(IF)時(shí)將發(fā)生什么.
◆服務(wù)端使用者舉例,一個(gè)接口去請(qǐng)求服務(wù)映射器給出實(shí)現(xiàn)那個(gè)接口的服務(wù)提供者的名稱
◆這個(gè)服務(wù)器映射器維護(hù)著一張服務(wù)和接口之間的映射關(guān)系表(通過(guò)查看dbus服務(wù)目錄,通常為/usr/share/dbus-1/services這個(gè)目錄)同時(shí)服務(wù)器映射器還有一套選擇服務(wù)的規(guī)則.它選擇一個(gè)服務(wù),然后將服務(wù)的名稱返回給SU的接口.
◆SU的接口接著創(chuàng)建一個(gè)正當(dāng)?shù)膁bus連接到一個(gè)已經(jīng)給出名稱的服務(wù),然后調(diào)用一個(gè)合適的方法
當(dāng)IF有一個(gè)新的SP時(shí),服務(wù)映射器就會(huì)發(fā)送一個(gè)信號(hào)給適當(dāng)?shù)腟U接口通知他們,或者如果IF沒有更多的SP,SU也會(huì)發(fā)送通知。當(dāng)有事件發(fā)生時(shí),應(yīng)用程序?qū)?huì)通過(guò)連接到在IF中的一個(gè)信號(hào)得到通知并采取相應(yīng)的動(dòng)作。例如,一個(gè)圖片應(yīng)用程序可能希望允許一個(gè)用戶通過(guò)EMAIL去發(fā)送一個(gè)照片,它可以監(jiān)聽“沒有更多的SP給IF”這個(gè)信號(hào),從而知道什么時(shí)候去使這個(gè)操作失效。
服務(wù)框架不應(yīng)該被使用做一般的IPC通訊或者例如介于兩個(gè)小程序之間的通訊,這些應(yīng)該使用其他方法來(lái)完成,例如,使用像DuiValueSpace一樣可以提供數(shù)值改變通知的數(shù)據(jù)后端的方法。
用法
作為一個(gè)服務(wù)提供者(SP)
◆SP的開發(fā)者需要準(zhǔn)備2樣?xùn)|西:
二進(jìn)制文件
當(dāng)一個(gè)服務(wù)端用戶應(yīng)用程序試圖連接到這個(gè)服務(wù)時(shí),這個(gè)二進(jìn)制文件將被加載(如果它沒有正在運(yùn)行)。
接口
服務(wù)端用戶應(yīng)用程序的開發(fā)者需要的文件包括如下內(nèi)容:
◆duiservicefwbaseif.h/cpp文件,這些文件對(duì)于所有的接口層都是通用的duiservicefwbaseif.h文件是libdui-dev包的一部分,duiservicefwbaseif.cpp會(huì)被編譯到libdui,所以他們都是libdui0包的一部分
◆需要給接口提供XML文件,頭文件,庫(kù)和一個(gè).serveice文件
接口特定的頭文件和接口的XML文件將共同成為maemo-interfaces-dev包的一部分,然后相應(yīng)的cpp文件需要編譯到接口特定的庫(kù)文件里面,這些庫(kù)又是maemo-interfaces包的一部分。.service文件也將會(huì)成為maemo-interfaces包的一部分。
二進(jìn)制文件
◆創(chuàng)建一個(gè)用于定義接口的XML文件.
如果你希望一個(gè)方法連接到當(dāng)前的應(yīng)用,你可以添加一個(gè)chainTask="true"屬性到這個(gè)方法標(biāo)簽。如果你希望一個(gè)方法是異步的,你可以添加一個(gè)asyncTask="true"屬性到這個(gè)方法的標(biāo)簽里。注意這些方法必須不含有任何的'out'參數(shù)。
例如:
- <!DOCTYPE node PUBLIC"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN""http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
- <node>
- <interfacenameinterfacename="com.nokia.TextProcessorInterface">
- <methodnamemethodname="reverse" chainTask="true">
- <arg name="message"type="s" direction="in"/>
- <arg name=""type="s" direction="out"/>
- </method>
- <method name="blinkScreen"asyncTask="true">
- <arg name="message"type="s" direction="in"/>
- </method>
- </interface>
- </node>
◆運(yùn)行dui-servicefwgen工具,產(chǎn)生相關(guān).h和.cpp文件,命令如下:
- dui-servicefwgen -acom.nokia.TextProcessorInterfac[font=宋體, SimSun]e[/font]
修改代碼
◆修改主要分為三個(gè)步驟,如下面的代碼段所示:
- //1.創(chuàng)建一個(gè)已經(jīng)實(shí)現(xiàn)接口功能函數(shù)的類實(shí)例
- MyService myService;
- //2.創(chuàng)建一個(gè)適配器去連接dbus和myService中的方法
- //按照QDBusAbstractAdaptor(),它必須是創(chuàng)建在堆上的,
- //并且內(nèi)存是由QDBusAbstractAdaptor管理的,因此不需要保存指針
- new MyServiceIfAdaptor( &myService );
- //3.連接到會(huì)話并注冊(cè)這個(gè)服務(wù)
- QDBusConnection connection =QDBusConnection::sessionBus();
- boolret=connection.registerService("com.nokia.TextProcessor");
- //繼續(xù)程序剩余的部分編寫
- return app.exec();
接口
定義一個(gè)接口有三個(gè)步驟:
◆創(chuàng)建一個(gè)定義接口的XML文件–與上面描述的是同一個(gè)XML文件.
◆運(yùn)行dui-servicefwgen這個(gè)工具,產(chǎn)生.h和.cpp文件,命令如下:
- dui-servicefwgen -pcom.nokia.TextProcessorInterface
◆需要產(chǎn)生服務(wù)相關(guān)的庫(kù).
以上的文件需要被放進(jìn)maemo-interfaces包,庫(kù)需要包含在maemo-interfaces里面,頭文件和XML文件也需要包含在maemo-interfaces-dev中。
接口和方法的文檔說(shuō)明可以加在'<doc>''</doc>'之間,例如:
- <interfacenameinterfacename="com.nokia.someserviceinterface">
- <doc>
- <argtagargtag="brief">brief documentation for the interface</arg>
- <argtagargtag="details">detailed documentation for theinterface</arg>
- </doc>
- <method name="showPage">
- <doc>
- <argtagargtag="brief">brief documentation for showPage()method</arg>
- <argtagargtag="details">detailed documentation for showPage()method</arg>
- </doc>
- <arg name="targetPage"type="s" direction="in" />
- <arg name="previousPage"type="s" direction="in" />
- <arg name="" type="b"direction="out"/>
- </method>
- ....etc
作為一個(gè)服務(wù)使用者
◆安裝libdui-dev debian包,它會(huì)提供給你服務(wù)映射dbus守護(hù)進(jìn)程,頭文件和庫(kù)文件。
◆安裝maemo-interfaces-dev包(包含代理頭、庫(kù)和封裝包的頭文件)
◆添加-ldui和-l<接口名字>到你工程文件的LIBS中。
◆在你的源文件中,包含這個(gè)接口頭文件,接著創(chuàng)建一個(gè)接口實(shí)例,然后調(diào)用serviceName()方法去得到這個(gè)接口的提供者
◆通過(guò)'isValid()'方法確認(rèn)這個(gè)服務(wù)是否可用。
◆調(diào)用想要用的接口方法。
實(shí)現(xiàn)并連接slots以處理有服務(wù)映射器發(fā)送出來(lái)'serviceAvailable()','serviceUnavailable()' 和'serviceChanged()'這些signals
演示和代碼例子
在libdui/demos/servicefw/中,有個(gè)例子示范了3個(gè)服務(wù)提供者和一個(gè)服務(wù)使用者。com.nokia.textprocessor和org.maemo.textprocessor服務(wù)都實(shí)現(xiàn)了相同的接口-com.nokia.TextProcessorInterface.因?yàn)橛?個(gè)服務(wù),所以我們可以嘗試去移除服務(wù),然后觀察服務(wù)用戶從一個(gè)服務(wù)轉(zhuǎn)換到另一個(gè)。有一個(gè)腳本工具/dui-servicefwgen,這個(gè)腳本工具被用來(lái)產(chǎn)生源文件,這些源文件是被用來(lái)給服務(wù)用戶定義接口的。下面開始運(yùn)行這個(gè)演示:
◆cd libdui
◆qmake && make && make instal(或者在duiservicemapper目錄中至少執(zhí)行一個(gè)make iinstall的操作)
◆cd demos/servicefw
◆pushd misc; sudo ./INSTALL; popd(這個(gè)操作將把dbus服務(wù)的相關(guān)文件安裝到/usr/share/dbus-1/services目錄中)
◆LD_LIBRARY_PATH=lib bin/user
◆這一步將打開一個(gè)小窗口允許你輸入字符,這些字符將通過(guò)接口發(fā)送到一個(gè)服務(wù)中,而服務(wù)將返回被反轉(zhuǎn)后的字符。
在這個(gè)演示中,你可以從/usr/share/dbus-1/services中移除若干個(gè)服務(wù)去模擬服務(wù)被移除的情況(然后再添加),以此來(lái)驗(yàn)證服務(wù)使用者程序是否能執(zhí)行正確的操作。
英文原文:http://apidocs.meego.com/mtf/servicefw.html
原文地址 http://www.meegoq.com/thread-250-1-1.html
【編輯推薦】