諾基亞symbian手冊匯編_第1頁
諾基亞symbian手冊匯編_第2頁
諾基亞symbian手冊匯編_第3頁
諾基亞symbian手冊匯編_第4頁
諾基亞symbian手冊匯編_第5頁
已閱讀5頁,還剩20頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、諾基亞symbian 手冊匯編Symbian OS Basics  Basic Types 在Symbian中,很多C+基本類型都被重新定義了,最好使用Symbian的,理由如下:· 所有Symbian API都是用的Symbianc重定義的 · 將來Symbian OS由32位轉(zhuǎn)為64位時(shí),支持性更好 · 這本身就是Symbian C+ Coding Standards所要求的Integers    typedef signed int TInt;  C+中的signed int,32位,基本用法類似。

2、    typedef unsigned int TUint;  一般用于計(jì)數(shù)器(Counter)或者標(biāo)記(Flags)。其他Int類型:TInt64, TInt32, TInt16,TInt8; 同時(shí)有一份TUint的版本。Text text類型在Symbian編程中基本不用,而一般采用描述符(descriptor)。TText默認(rèn)是16位的。Boolean     typedef int TBool; 有兩個(gè)枚舉值:ETrue和EFalse。TBool變量最好不要直接和ETure和EFalse比較。如下:TBo

3、ol flag = ETrue;if (flag)  / if (!flag)     flag = EFalse; Floating Point    對浮點(diǎn)數(shù)的支持視處理器而定,如果沒有FPU,效率非常低,所以最好是不要用浮點(diǎn)數(shù)。 如果一定要用,盡量轉(zhuǎn)化為整數(shù)操作。typedef float TReal32;  typedef double TReal64; typedef double TReal;TAny     typedef void TAny;TAny一般只用作指針,其他情況下用v

4、oid比較好。TAny* MyFunction();     void MyOtherFn();TAny* 在很多Symbian API中都用到了,如:static TUint8* Copy( TAny* aTrg, const TAny* aSrc, TInt aLength);Enumerations enum TState EOff, Eon, EInit;Enumeration類型應(yīng)該以T開頭,而枚舉值應(yīng)該以E開頭。 TState  state = GetState();if (state = EOn)   

5、;/Do something here Coding Conventions    T類:只包含值,而不包含指針以及外部的資源,在棧上分配空間。TVersion osVersion = User:Version();    C類:所有需要分配內(nèi)存的類都必須從CBase繼承并且以C開頭。class CExample : public CBaseprivate:   CDesCArrayFlat* iArray;    CExample* example = new (ELeave) CExample;  &

6、#160; R類:包含指向某個(gè)資源的handler。RTimer timer;timer.CreateLocal();    M類:定義一個(gè)接口,一般只包含純虛函數(shù),不包含成員數(shù)據(jù),減少類之間的依賴,用來接受回調(diào)消息。class MEikStatusPaneObserver   public:        virtual void HandleStatusPaneSizeChange() = 0;任何實(shí)現(xiàn)MEikStatusPaneObserver接口的類都必須實(shí)現(xiàn)HandleStatusPa

7、neSizeChange()函數(shù)。Variable Naming Conventions ·     成員變量以“i”開頭 ·     參數(shù)以“a”開頭 ·     動態(tài)變量隨便,以小寫字母開頭 ·     常量以“K”開頭 ·     盡量不要使用全局變量,不能使用全局靜態(tài)變量。Functions ·     函數(shù)以大寫字母開頭,如AddFileNameL(); ·     以D結(jié)尾表

8、示deletion of an object ·     以L結(jié)尾表示函數(shù)可能leave ·     以C結(jié)尾表示一個(gè)item被放到cleanup stackCasting    Casting用于在類(classes)和類型(types)之間作轉(zhuǎn)化,Symbian中仍然可以使用C中語法。    dynamic_cast:不支持,Symbian中沒有RTTI。    static_cast:把一個(gè)基類轉(zhuǎn)化為一個(gè)繼承類。 TInt intValue = 0xff;TUint8

9、byteValue = static_cast<TUint8>(intValue);     reinterpret_cast:把一個(gè)指針類型轉(zhuǎn)化為另外一個(gè)指針類型,如integer轉(zhuǎn)化為point類型或者相反。TUint32 fourBytes = 0;TUint8* bytePtr = reinterpret_cast<TUint8*> (&fourBytes);bytePtr+;*bytePtr = 0xFF;     const_cast:移除一個(gè)類的const屬性。內(nèi)存管理Why Memory Managemen

10、t    Symbian OS本身就是為內(nèi)存和資源受限的設(shè)備開發(fā)的,應(yīng)用程序運(yùn)行過程中很可能碰到內(nèi)存用光,或者硬件資源不可用的情況。而這種exceptions是通過修改程序無法解決的,所以遵守以下幾條:盡量不要使用不必要的RAM盡早釋放資源,如文件server等當(dāng)你每次申請內(nèi)存時(shí),都須準(zhǔn)備處理out-of-memory錯(cuò)誤當(dāng) out-of-memory錯(cuò)誤發(fā)生時(shí),返回到一個(gè)stable的狀態(tài),并釋放所有期間申請到的資源Stack and Heap    Stack:默認(rèn)大小8kb,自動刪除,如 TInt i = 0;    Heap

11、:至少.5Mb,由程序員手動刪除,如 CMyObj* obj = new (ELeave) CMyObj;Leaves    首先介紹Conventional C+ Memory Management,在Symbian看來,這是非常低效率的。NULL Pointer Checking  if (myObj = new CMyObj( ) ) = NULL) /Error Handling ANSI C+ Exeption Handling   try /throw an Exception catch (int e) /Error H

12、andling     在Symbian中推薦采用Leave,如果內(nèi)存或者資源不能分配到,這個(gè)代碼就會Leave,沿著Call Stack,直到操作系統(tǒng)或者在某個(gè)函數(shù)中被Handle掉。    所有可能Leave的函數(shù)最好以L結(jié)尾,保證該函數(shù)的用戶知道這個(gè)函數(shù)可能Leave。    Leave的例子:動態(tài)內(nèi)存分配: return new (ELeave) TUint81000;產(chǎn)生一個(gè)Leave:User:Leave(KErrNotFound);內(nèi)存不足時(shí)Leave:User:LeaveNoMemory();NULL的時(shí)候Leave:

13、User:LeaveIfNull(aNotify);當(dāng)發(fā)生錯(cuò)誤時(shí)Leave:RFs fs; TInt err = fs.Connect(); User:LeaveIfError(err);    處理Leave:    操作系統(tǒng)有默認(rèn)的處理Leave的方式:在程序啟動過程中:直接關(guān)閉應(yīng)用程序。應(yīng)用程序啟動后:顯示一個(gè)錯(cuò)誤消息。     開發(fā)者可以通過trap裝置來處理Leave。TRAP(_r, _s)和TRAPD(_r, _s),其中:_r:是一個(gè)TInt類型的leave code,默認(rèn)值為TErrNone。_s:一系列可能Leav

14、e的C+ Statements。        TRAPD(err, DoFunctionL();        if (err != KErrNone)         /Error Handling         else         /Everything is well  &

15、#160;The Cleanup Stack    cleanup stack用于存儲在leave發(fā)生后需要deallocating的局部變量(指針)。即:當(dāng)一個(gè)函數(shù)leave了,所有在cleanup stack上的對象會被全部刪除掉。    Cleanup Stack的使用方法:CleanupStack:PushL(ptr) :當(dāng)發(fā)生leave時(shí)所有內(nèi)存都會被釋放CleanupClosePushL(handle):當(dāng)發(fā)生leave時(shí)這個(gè)句柄(handler)會被關(guān)閉CleanupStack:Pop(pointer):第一個(gè)元素出棧CleanupStac

16、k:PopAndDestroy(pointer):第一個(gè)元素出棧并釋放內(nèi)存    如果一個(gè)函數(shù)可能leave,檢查一下兩種情況:如果leave了,是否所有在堆(heap)上的元素都在cleanup stack中了如果沒有l(wèi)eave,你是否自己恰當(dāng)?shù)貙⑺鹀leanup了CMyClass* CMyClass:NewL(TInt aBufSize)   CMyClass* self = new (ELeave) CMyClass;   CleanupStack:PushL(self);   self->Constr

17、uctL(aBufSize);   CleanupStack:Pop(self);   return self;    如果某個(gè)函數(shù)會在cleanup stack上留下一個(gè)對象,那么他必須以C結(jié)尾。Two Phase Construction    C+構(gòu)造函數(shù)一定不能leave。所有內(nèi)存和資源的分配應(yīng)該在第二階段構(gòu)造函數(shù)ConstructL( )中完成。編碼指南,所有用戶定義的C類必須:定義NewL和NewLC函數(shù)為public static定義ConstructL和C+ Constructor為privateB

18、est Practise     Construction的規(guī)則:默認(rèn)的C+構(gòu)造函數(shù)中不能含有可能leave的代碼可能發(fā)生leave的函數(shù)必須在ConstructL中被調(diào)用如果基類也有ConstructL,必須首先調(diào)用,不要忘了explicit scoping    Destruction的規(guī)則:C類必須在析構(gòu)函數(shù)中刪除它自己所包含的對象在刪除一個(gè)對象后,把它的指針設(shè)為NULL不要刪除不是本類所擁有的對象在reallocation前首先刪除對象,并且將其指針設(shè)為NULL    Further Discussion:

19、Preserve Stack Memory:每個(gè)進(jìn)程只有8K,以引用的方式傳遞參數(shù),大的對象放在堆上Preallocation vs last moment allocation:一般的原則是只在使用前分配資源并且在使用后馬上釋放。但是                     preallocation的好處是節(jié)約處理時(shí)間,并且在沒有內(nèi)存的情況下照常運(yùn)行(資源已經(jīng)分配到了)where to put trap harness:最基本的情況是依靠GUI應(yīng)用程序

20、的框架。根據(jù)應(yīng)用的不同,可以自定義粒度。Error Code Returns vs. leaving functions:在執(zhí)行某個(gè)處理前檢測是否會出現(xiàn)問題,如下代碼:                                    User:LeaveIfError(fs.Connect(); Memory Leaks    如果

21、你的程序有內(nèi)存泄露,在模擬器上關(guān)閉時(shí)會crash。盡早發(fā)現(xiàn)并解決你的內(nèi)存泄露,因?yàn)槟憧梢宰凡榈侥憧赡軐?dǎo)致內(nèi)存泄露的代碼改動。如果實(shí)在找不到,可用下面方法:    Heap Balance Checking:_UHEAP_MARK_UHEAP_MARKEND    用上述這兩個(gè)宏放在你要檢查的代碼的開頭和結(jié)尾,如果發(fā)生panic,則說明這段代碼中發(fā)生了內(nèi)存泄露??梢郧短资褂?。 Panics     Panic是一個(gè)未經(jīng)處理的exception,暗示著一個(gè)無法解決的錯(cuò)誤。一般程序有以下三類錯(cuò)誤:程序錯(cuò)誤:如引用一個(gè)超過數(shù)組范圍的元素環(huán)境錯(cuò)

22、誤:內(nèi)存、磁盤空間不夠,或缺少其他資源等用戶錯(cuò)誤:輸入錯(cuò)誤數(shù)據(jù)    可以使用trap和cleanup stack技術(shù)來解決環(huán)境和用戶錯(cuò)誤,但是對于第一類的程序錯(cuò)誤,我們無法恢復(fù),最好是使用User:Panic()函數(shù),它帶有兩個(gè)參數(shù),第一個(gè)是string,第二個(gè)是Tint。描述符Introduction    描述符(Descriptors)封裝了字符串和二進(jìn)制數(shù)據(jù),用于替代C中的以NULL結(jié)尾的字符串。它的長度和數(shù)據(jù)都封裝在了描述符中,Symbian API中用的都是描述符。如:    TPtrC ptr (KHelloWorld

23、);    CEikonEnv:Static()->InfoMsg(ptr);Main Types of Descriptors    主要可以分為以下幾類,其中帶C的是不可修改的。 · Abstract:(TDes、TDesC),其他描述符的基類,不能實(shí)例化,一般用作函數(shù)的參數(shù)。 · Literal:(TLitC,_LIT()),用于存儲literal string,一般使用后者。 · Buffer:(TBuf,TBufC),數(shù)據(jù)存儲于棧上,大小在編譯時(shí)確定。 · Heap:(HBufC),數(shù)據(jù)存儲于堆上,

24、大小在運(yùn)行時(shí)確定。 · Pointer:(TPtr,TPtrC),引用存儲于類之外的數(shù)據(jù)Descriptor Modification    描述符可以是可修改的和不可修改的,通常帶C的都是不可修改的,不可修改的是可修改的基類。   · Moidfiable:提供了訪問和修改數(shù)據(jù)的API,如TBuf · Non-Modifiable:數(shù)據(jù)只可以被訪問,不可修改。但是通過Des()函數(shù)可返回一個(gè)可修改的指針Descriptor Width    在描述符類后加上8或者16影響了存儲在描述符中的數(shù)據(jù)的寬度,默

25、認(rèn)是16位的,處理二進(jìn)制或ASCII時(shí)采用8位。· 8位:(TDesC8),用于二進(jìn)制數(shù)據(jù)或者ASCII字符串 · 16位:(TDesC16),默認(rèn),Unicode下面開始對上述5類描述符進(jìn)行詳細(xì)介紹,首先看一下類繼承關(guān)系                                         

26、60; 這里顯示的是8位的,16位默認(rèn)的類繼承關(guān)系與此一致Abstract Descriptors    除Literal外的所有描述符的基類,提供了基本的接口和基礎(chǔ)功能。他們本身不能實(shí)例化,一般用作函數(shù)參數(shù)。TDesC:提供了比較、復(fù)制、搜索、提取部分字符串的函數(shù)。TInt TDesCUtil:SumLengths(const TDesc& aDesC1, const TDesc& aDesC2)   return aDesC1.Length() + aDesC2.Length();  TDes:繼承自TDesC,添

27、加了許多用于修改數(shù)據(jù)的函數(shù)。其最大長度是描述符被創(chuàng)建時(shí)確定的。TInt TDesCUtil:AppendL(TDesc& aTarget, const TDesc& aDesC)   TInt sumLen = aTarget.Length() + aDesC.Length();   if (aTarget.MaxLength() < sumLen)         User:Leave(KErrOverflow);      aTa

28、rget.AppendL(aDesC); Literal Descriptors    提供了一種將字符串放在只讀存儲空間中的機(jī)制(實(shí)際存放在程序的數(shù)據(jù)區(qū),而不是真的在ROM中)。一般不采用TLitC而直接采用_LIT()宏。    _LIT(KHelloWorld, "Hello World!");    通過()操作符可以得到 const TDesC&。 TInt length = KHelloWorld().Length();    在函數(shù)參數(shù)為const TDesC&可以

29、直接使用KHelloWorld。iLabel->SetTextL(KHelloWorld);Buffer Descriptors    將數(shù)據(jù)作為本身的一部分存儲在stack上,他們的最大長度是在編譯時(shí)確定的。  TBuf<16> helloWorld = KHelloWorld;TInt len = KHelloWorld().Length();helloWorldlen-1='?' 在內(nèi)存中如下所示: TBufC的用法如下:_LIT(KHelloWorld, "Hello World");cons

30、t TInt maxBuf = 32;TBufC<maxBuf> buf;TInt currentLen = buf.Length(); / = 0buf = KHelloWorld;currentLen = buf.Length(); / = 11TText ch = buf2; / = 'l'TBuf的用法如下:const TInt bufLen = 6;TUInt8 objType = 1;TUInt8 objId = 1;TUInt8 xCoord = 128;TUInt8 yCoord = 192;.TBuf8<bufLen> buf; buf

31、.Append(objType);buf.Append(objId);./we can now do something with the buffer such as writting it to a binary file or send via socket.Pointer Descriptor    用于引用存儲在其他地方的數(shù)據(jù),如:const unsigned char KBuffer = 0x00, 0x33, 0x66, 0x99, 0xbb, 0xff;TPtrC8 bufferPtr( KBuffer, sizeof(KBuffer);iSocket.Wr

32、ite(bufferPtr, iStatus);在內(nèi)存中如下所示:TPtr的用法:_LIT(KHelloWorld, "Hello World");const TInt maxBuf = 32;TBufC<maxBuf> buf;buf = KHelloWorld;TPtr ptr = buf.Des();ptr7 = 'a'  ptr8 = 'l'  ptr9 = 'e'  ptr10 = 's'  CEikonEnv

33、:Static()->InfoMsg(ptr); / "Hello Wales"Heap Descriptors     動態(tài)在堆(heap)上分配,通過HBufC的API,數(shù)據(jù)可以被set和reset,但是不能被修改。如:HBufC* heapBuf = HBufC:NewL(KHelloWorld().Length();*heapBuf = KHelloWorld();delete heapBuf;      在內(nèi)存中的情況如下圖所示:    HBufC通常在以下幾

34、種情況下使用: · 在運(yùn)行時(shí)從資源文件中加載字符串 · 從用戶界面中接收用戶輸入的字符串 · 從應(yīng)用程序引擎中接收字符串,如contacts database中的名字     對HBufC中的內(nèi)容進(jìn)行修改:_LIT(KHello, "Hello!");_LIT(KWorld, "World!"); HBufC* heapBuf = HBufC:NewL(KHello().Length();*heapBuf = KHello;    /buf holds "

35、Hello!"heapBuf = heapBuf->ReAllocL(KHello().Length() + KWorld().Length();CleanupStack:PushL(heapBuf);TPtr ptr (heapBuf->Des();  /DON'T use TPtr ptr = heapBuf->Des(); this will set maxlen to 6 but not 12.ptrKHello().Length() - 1 = ' 'ptr += KWorld;iTopLabel -> S

36、etTextL(ptr);CleanupStack:PopAndDestroy();DrawNow();下面介紹Descriptors的具體用法: Non-Modifying Methods     Length(),Size(),Left(),Right(),Mid(),Compare(),Locate(),LocateReverse(),F(xiàn)ind(),Match()等。以下代碼示例描述了如何在一個(gè)descriptor中找到<>中的內(nèi)容,如果不存在,返回整個(gè)字符串:static const TUint KAddressStartChar =

37、 '<' static const TUint KAddressEndChar = '>'TPtrC ExtractAddressNumber( const TDesC& aAddressString)    TInt addrStart = aAddressString.Locate(KAddressStartChar ) + 1;    TInt addrEnd  = aAddressString.LocateReverse(KAddressEndChar ) ;  &

38、#160; if (addrStart = KErrNotFound) | (addrEnd = KErrNotFound) | (addrStart >= addrEnd) )            addrStart = 0;        addEnd    = aAddressString.Length();        return (aAddressString.Mid(add

39、rStart, (addrEnd - addrStart) ) ); Modifying Methods     Zero(),Copy(),Num(),F(xiàn)ormat(),Insert(),Replace(),Delete(),Append(),Trim()等。代碼示例:_LIT(KText, "Hello World!");_LIT(KNewText, "New Text");_LIT(KReplaced, "Replaced");TBuf<16> buf1(KText); buf

40、1.Delete(6, 6); / length is now 6, leaving "Hello" in the bufferTBuf<16> buf2(KNewText);buf2.Copy(KReplaced); / buf2 now contains "Replaced"buf2.Append(KNewText);  /buf2 now contains "Replaced New Text"buf2.Delete(99, 1); /Will Cause a PANIC! Descriptors

41、 in Method Declarations · 在函數(shù)參數(shù)中盡量使用基類 · 使用中性的描述符,一般情況下使用TDesC而不是TDesC8或者TDesC16 · 當(dāng)描述符內(nèi)容不應(yīng)該改變時(shí),使用const修飾符 · 經(jīng)典用法:void SetText(const TDesC& aText);    TPtrC Text() const;   Character Conversions        CCnvCharacterSetConverte

42、r類提供了在Unicode和其他字符集編碼之間轉(zhuǎn)換的方法。ASCII本來就是Unicode的一個(gè)子集,無須使用該類。和Unicode之間的轉(zhuǎn)換方法如下所示:TBuf16<64>  UnicodeBuf;_LIT8(KAsciiStr, "Hello");UnicodeBuf.Copy(KAsciiStr); Unicode和拉丁語系之間的轉(zhuǎn)化可使用如下的代碼:TBuf8<64> Latin1Buf;_LIT16(KUnicodeStr1, "hello");_LIT16(KUnicodeStr2, "

43、I have got 10x20AC.");  /x20AC is a euroLatin1Buf.Copy(KUnicodeStr1); /OKLatin1Buf.Copy(KUnicdoeStr2); /Not as you wanted.Symbian操作系統(tǒng)將應(yīng)用程序設(shè)計(jì)為單線程的,在大多數(shù)情況下等待異步事件的產(chǎn)生和完成。雖然可以使用多線程,但是不提倡這種做法,一方面是上下文切換開銷導(dǎo)致電池使用壽命降低,另外一方面就是開發(fā)較復(fù)雜。    Symbian使用Active Object框架來處理操作系統(tǒng)的異步事件處理特性。由兩方面構(gòu)成:&#

44、183; The Active Scheduler: 用來調(diào)度事件,每個(gè)線程只能有一個(gè) · Active Objects:這些對象用于處理事件,在一個(gè)線程中可以有多個(gè)Asynchoronous Functions     Symbian OS中包含很多異步函數(shù),任何含有TRequestStatus&參數(shù)的函數(shù)都是異步的。如:void After (TRequestStatus& aStatus, TTimeIntervalMicroSeconds32 aInterval)· TRequestStatus:包含一個(gè)TIn

45、t類型的狀態(tài)值,調(diào)用時(shí)值為TRequestStatus · 時(shí)間請求當(dāng)且僅當(dāng)aStatus != TRequestStatus時(shí)完成,而非函數(shù)返回時(shí)完成Synchoronous Functions    先看如下例子:創(chuàng)建一個(gè)Timer,并且請求一個(gè)10秒的timeout。RTimer timer;timer.CreateLocal();TRequestStatus status;timer.After(status, 10000000);User:WaitForRequest(status);    這是同步調(diào)用,即當(dāng)User:WaitFor

46、Request(status);執(zhí)行時(shí),其他事件都被掛起,用戶界面停止響應(yīng)。一個(gè)比較好的解決辦法是:當(dāng)時(shí)間請求結(jié)束后收到一個(gè)通知,而在該過程中其他事件可以被處理。Active Objects       可以被用來處理異步函數(shù)調(diào)用。從CActive繼承,并有如下成員變量:優(yōu)先級決定了何時(shí)被檢查是否完成· TRequestStatus:類成員變量,iStatus,傳入異步函數(shù)調(diào)用 · RunL():當(dāng)異步請求結(jié)束時(shí)被調(diào)用 · DoCancel():當(dāng)異步請求被取消時(shí)調(diào)用Active Scheduler   

47、 當(dāng)應(yīng)用程序啟動時(shí),都包含一個(gè)系統(tǒng)創(chuàng)建的默認(rèn)Active Scheduler。在主線程中進(jìn)行事件循環(huán),完成以下功能;· 同步等待任何發(fā)出請求的結(jié)束 · 根據(jù)優(yōu)先級測試每個(gè)注冊的active object,看是否有發(fā)出的請求、它的請求是否已經(jīng)結(jié)束 · 對于每個(gè)請求已經(jīng)完成的active object,調(diào)用其RunL()函數(shù) · 在RunL()返回后,再檢查其他請求 · 對于RunL()可能Leave的情況,調(diào)用需函數(shù)RunError()    通過 static void Add ( CActive* aActive)函數(shù)將一

48、個(gè)active object注冊到active scheduler中。 Implementing Active Objects    要實(shí)現(xiàn)一個(gè)Active Object,必須遵循以下步驟:· 從CActive繼承 · C+構(gòu)造函數(shù)中:設(shè)置優(yōu)先級EPriorityStandard,調(diào)用CActiveScheduler:Add() · 提供一個(gè)進(jìn)行異步函數(shù)調(diào)用的成員函數(shù),傳入:CActive:iStatus,調(diào)用CActive:SetActive() · 實(shí)現(xiàn)RunL()和DoCancel()函數(shù),因?yàn)樗麄兌际羌兲摵瘮?shù),必須實(shí)現(xiàn) 

49、83; 在析構(gòu)函數(shù)中調(diào)用CActive:Cancel()    Symbian中的CPeriodic類已經(jīng)是一個(gè)對timer封裝的active object了。    上圖展示了Active Object使用的調(diào)用流程。Active Objects Other uses· 處理異步函數(shù)調(diào)用 · 將處理器開銷大的任務(wù)分成幾個(gè)階段 · 實(shí)現(xiàn)一個(gè)異步服務(wù) · 調(diào)用一系列的異步函數(shù)客戶端/服務(wù)器框架本課從用戶角度學(xué)習(xí)客戶端/服務(wù)器框架,關(guān)注如何使用客戶端API而非實(shí)現(xiàn)服務(wù)器端功能。Introduction  &#

50、160; Symbian OS使用客戶端/服務(wù)器框架來訪問系統(tǒng)資源:如打開文件、撥打、設(shè)置鬧鐘等。需要由服務(wù)器來管理系統(tǒng)資源來防止多個(gè)客戶訪問可能引起的問題。    服務(wù)器運(yùn)行在自己的進(jìn)程或者線程空間中,任何來自客戶端的請求都要穿過線程邊界。這表明:服務(wù)器對資源有著絕對的控制權(quán),可以拒絕來自客戶端的請求(如一個(gè)客戶端請求刪除另外一個(gè)客戶端正在編輯的文件)。 Example Servers and Client APIs    Symbian OS主要包含的服務(wù)器,如下圖所示,其中:· 藍(lán)色:在自己的進(jìn)程空間中 · 綠色:在一個(gè)線程空間

51、中,與其他服務(wù)器共享一個(gè)進(jìn)程     在每個(gè)Server中列出的類描述了客戶端可以使用的API,以下是每個(gè)服務(wù)的概述:Kernel Server:運(yùn)行在最高權(quán)限,管理系統(tǒng)中所有其他進(jìn)程對硬件和內(nèi)存的訪問。· RTimer:提供異步時(shí)間服務(wù) · RThread: 提供線程訪問和創(chuàng)建 · RSemaphre:提供線程間同步機(jī)制File Server:提供了對文件系統(tǒng)的訪問· RFs:提供到文件服務(wù)器的一個(gè)會話,可以完成高層次的驅(qū)動器、目錄和文件的操作以及獲取目錄列表 · RFile:提供文件創(chuàng)建、讀取和寫入操

52、作 · RDir:讀取目錄中所含的entriesWindow Server:應(yīng)用程序框架使用窗口服務(wù)器來處理按鍵事件以及進(jìn)行屏幕顯示操作· RWindow:提供屏幕顯示操作,開發(fā)人員一般使用CCoeControl:raw() · RAnim:與服務(wù)器端animation通信(服務(wù)器端高優(yōu)先級drawing) · CWindowGc:提供屏幕繪圖操作的圖形上下文Font and Bitmap Server:在客戶端之間共享字體和位圖· RFbsSession:負(fù)責(zé)與字體和位圖服務(wù)器之間的一個(gè)會話,程序開發(fā)中一般不使用該類 · CFbsB

53、itmap:表示一個(gè)位圖 · CFbsDevice:表示一個(gè)用于顯示位圖的圖形設(shè)備Telephony Server:負(fù)責(zé)設(shè)備的功能· RTelServer:提供到服務(wù)器的工具級別的訪問 · RPhone:提供設(shè)備上操作 · RLine:提供一路的操作 · RCall:提供在某一路上撥打/接收的功能Socket Server:提供通過多種媒體創(chuàng)建一個(gè)TCP/IP或者UDP的socket· RSocketServ:連接到Socket服務(wù)器,發(fā)現(xiàn)所有的協(xié)議 · RSocket:提供連接到,接收和發(fā)送數(shù)據(jù)到另外一個(gè)socket的功能

54、 · RHostResolver:提供DNS解析功能Comms Server:允許開發(fā)者通過電纜或者紅外使用串行口· RCommServ:提供一個(gè)到Comms Server的會話 · RComm:提供通過串行口通行的功能Message Server:保存消息數(shù)據(jù)并且提供到消息功能如SMS,MMS,OBEX和Mail的訪問· CMsvSession:描述一個(gè)和消息服務(wù)器的會話 · CMsvEntry:描述消息stroe中的一個(gè)entry · CBaseMtm:提供訪問和操作消息服務(wù)器entry的接口Server Plug-ins

55、0;   客戶端/服務(wù)器架構(gòu)具有很好的可擴(kuò)展性,許多服務(wù)器都允許添加plug-in模塊,為新的技術(shù)、協(xié)議和媒質(zhì)提供功能。所添加的新功能可以通過一個(gè)generic api進(jìn)行訪問。如:· Message Server:MMS,SMS,POP3,SMTP · Socket Server:紅外,藍(lán)牙,CSD(Circuit Switched Data)Sessions     下圖展示了不同的客戶端/服務(wù)器會話場景:Client1:和服務(wù)器之間只有一個(gè)會話,在應(yīng)用程序的control environment中與文件服務(wù)器的默認(rèn)會話。Client2:和

56、服務(wù)器之間有兩個(gè)會話,除默認(rèn)會話外還有一個(gè)顯式的文件操作。Client3:和服務(wù)器之間有一個(gè)會話和兩個(gè)字會話,與文件服務(wù)器有一個(gè)連接,對每個(gè)打開的文件分別由一個(gè)會話。 Requests    下圖展示了一個(gè)客戶端如何穿越線程邊界與服務(wù)器進(jìn)行通信,RSessionBase等類都是基類,需要繼承。具體過程如下:· 調(diào)用一個(gè)客戶端接口所提供的API,如RFs:rive(),來獲取驅(qū)動器信息 · RSessionBase:SendReceive()被調(diào)用,參數(shù)為操作碼和一個(gè)包含4個(gè)指向客戶端內(nèi)存指針的數(shù)組 · 內(nèi)部的private函數(shù)RSessionB

57、ase:SendSync()被調(diào)用,訪問內(nèi)核 · 內(nèi)核調(diào)用服務(wù)器線程中的CSession2:ServiceL(), 封裝了消息內(nèi)容的RMessage2作為參數(shù) · 調(diào)用RMessage2:WriteL()在用戶端的空間中寫入所需要的數(shù)據(jù) · 調(diào)用RMessage2:Complete()來表示對客戶端請求的完成Using Client APIs    客戶端API繼承自RSessionBase或者RSubSessionBase,必須以以下順序使用:· 建立到相應(yīng)的服務(wù)器的連接,一般通過函數(shù)Connect()或者Open()。 ·

58、; 在建立連接后,可以使用所有的API,請求可以通過同步或者異步的方式發(fā)送。 · 在使用完后必須關(guān)閉到服務(wù)器的連接,否則將發(fā)生資源泄漏    需要注意的是:可能會發(fā)生leave,資源必須使用CleanupClosePushL()放到cleanup stack上。    ClientAPI的使用案例:HBufC* CFileUtil:ReadL(const TDesC& aFileName)   RFs fs;   User:eaveIfError(fs.Connect();   

59、;CleanupClosePushL(fs);   RFile file;   User:eaveIfError(file.Open(fs, aFileName, EFileRead);   CleanupClosePushL(file);   TInt fileSize;   file.Size(fileSize);   HBufC8* data = HBufC8:NewL(fileSize);   file.Read(data);  

60、0;CleanupStack:opAndDestroy(2);   return data;資源文件資源文件 · 指定了應(yīng)用程序的相關(guān)信息,包含要顯示的控件定義(如菜單,對話框等),是所有應(yīng)用程序所必須的。 · 資源文件的后綴名為<application name>.rss。最多可以包含4095個(gè)資源。 · 一個(gè)應(yīng)用程序可以包含多個(gè)資源文件,并在運(yùn)行時(shí)動態(tài)加載其他資源文件。 · Uikon預(yù)先定義了許多在資源文件中可以使用的結(jié)構(gòu)體。 · 資源文件需要編譯成二進(jìn)制文件,在C+代碼中需要include編譯產(chǎn)生的.rs

61、g文件。具體的文件及解釋如下: / 4 letter ID 該字段必須每個(gè)應(yīng)用程序唯一NAME S60R    /  INCLUDES  包含已經(jīng)定義的資源結(jié)構(gòu)#include <eikon.rh>#include <avkon.rh>#include <avkon.rsg>#include <appinfo.rh>/hrh用于包含枚舉常量,如菜單項(xiàng);rls定義了在UI中使用的字符串#include "S60ResourceLab.hrh"#include "

62、;S60ResourceLab.rls"/允許應(yīng)用程序指定版本號,可選RESOURCE RSS_SIGNATURE        /為該應(yīng)用程序的默認(rèn)文件指定一個(gè)名字RESOURCE TBUF r_default_document_name        buf="HEWB"    /指定了所要顯示的菜單和soft keysRESOURCE EIK_APP_INFO        menubar=r_s60resourcela

63、b_menubar;    cba=R_AVKON_SOFTKEYS_OPTIONS_BACK;    菜單相關(guān):/定義了需要顯示的menu pane,txt字段為空(S80中才有位置顯示菜單的title,S60沒有)RESOURCE MENU_BAR r_s60resourcelab_menubar        titles=                MENU_TITLE menu_pa

64、ne=r_s60resourcelab_menu; txt=""             /menu pane定義了一系列menu items,command就是HandleCommandL中接收的命令參數(shù),txt顯示給用戶。RESOURCE MENU_PANE r_s60resourcelab_menu        items=              

65、;  MENU_ITEM command=EAknCmdExit; txt="Exit" ,        MENU_ITEM command=ES60ResourceLabCmdAppTest; txt="Test"             字符串相關(guān):字符串的內(nèi)容真正定義的位置是在本地化文件中,見后。RESOURCE TBUF r_s60resourcelab_text_goodbye

66、0;       buf = qtn_s60resourcelab_text_goodbye;    RESOURCE TBUF r_s60resourcelab_text_everyone        buf = qtn_s60resourcelab_text_everyone;    Localisation Files    每種顯示給用于的語言都有一個(gè)本地化文件,在該文件中包含所有需要翻譯的語言??梢栽趓ss文件中被條件包含,如下所示:#ifdef LAN

67、GUAGE_01    #include "HelloWorld01.rls"#elif defined LANGUAGE_02    #include "HelloWorld02.rls"#endif     示例:keyword symbolic_identifier the_stringrls_string qtn_caption_string "S60 Resource Lab"rls_string qtn_s60resourcelab_text_goodbye "Goodbye"Resource Compilation    資源編譯器將rss文件編譯為rsc文件,中間產(chǎn)生一個(gè)rsg的頭文件。    C+代碼中使用resource需要包含rsg頭文件,使用方法如下:HBufC* textResource = StringLoader

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論