Symbian應用程序常用架構

Symbian應用程序常用架構

2006-11-10      嵌入式在線      收藏 | 打印

  所謂“應用程序架構”是指應用程序框架類的集合 基於所需的UI設計,應用程序可以具有稍微不同的架構,但是每種架構都有一些公共部分,稱爲“核心應用程序類”<?XML:NAMESPACE PREFIX = O />

一、先看一下基礎部分,具體架構在第二部分介紹

1)核心應用程序類.

所有的S60 UI應用程序都具有一些基本功能:

l         提供一個用戶界面,用於顯示信息並允許用戶進行交互

l         響應各種用戶啓動的事件,比如用戶選擇一個菜單項

l         響應系統啓動的不同事件,比如導致屏幕重繪的window服務器事件

l         能夠保存和恢復應用程序數據

l         可以唯一性的向框架標誌自身

l         向框架提供有關應用程序的描述性信息,比如圖標和標題等

這些類是:視圖(View)、文檔(Document)、應用程序(Application)、應用程序UI(Application UI)。

<?XML:NAMESPACE PREFIX = V />

  

一個程序只能有一個文檔,可以有多個視圖。

2)應用程序初始化

必須創建下面的每個方法,才能提供最小的S60應用程序:

a、  所有S60 UI都實現一個全局函數E32DLL(),當應用程序啓動時,框架將首先調用該函數,該函數也稱爲DLL入口點,應用程序必須存在該函數。每個S60 UI 應用程序都是一個多態DLL

b、  讓框架調用NewApplication(),該函數是由DLL導出的唯一函數。

c、  創建應用程序類的一個實例,並返回它的指針,以後框架使用該指針完成應用程序的創建。

d、  由框架調用AppDllUid()返回應用程序的UID。該函數必須返回在.mmp文件中指定的值,並且可用於確定應用程序的實例是否正在運行。

e、  框架獲取指向新創建Document類的指針,CreateDocumentL()。

f、   NewL()具體去創建

g、  礦見獲取AppUi類的指針,CreateAppUiL()。

h、  new EleaveCappUi()具體創建。

這樣一個最簡短直觀的框架就創建完畢。

3)重要的AppUi方法:

AppUi提供了許多方法,框架可以調用這些方法通知每個應用程序各種事件。

l         HandKeyEvent()用於處理用戶按鍵

l         HandleForegroundEventL()當應用程序切換到前臺或從前臺切換到後臺時調用該函數,默認的實現可以處理鍵盤焦點的改變。

l         HandleSystemEventL()傳遞由窗口服務器生成的事件

l         HandleApplicationSpecificEventL()可以自己定義的自定義事件的通知。默認的實現可以處理顏色方案改變的通知。

l         HandleCommandL()用於處理用戶選擇的菜單項

4)設計應用程序UI

關於術語“視圖(view)”:

l         “視圖”是概念性的術語,含義是“數據模型在屏幕上的表示”,實際上由一個或多個從CcoeControl派生而來的UI控件實現視圖,這些控件按層次結構進行組織。父控件通常被稱爲容器(Container),除了用於實現視圖的父控件,這種控件被稱爲對話框(Dialog

l         Avkon視圖切換架構中,術語“Avkon視圖”指的是系統範圍內的View服務器註冊的類,它控制視圖的實例化和析構。

二、常見的symbian應用程序架構:

每種架構都提供了設計應用程序UI的不同方法――所有的架構都提供了提交“視圖”或應用程序數據可視化表示的方法,同時提供了一種用戶用來與架構進行交互的機制。

先簡單認識一下:基於對話框的架構和傳統的基於Symbian OS的架構雖不相同,但和Avkon視圖切換架構相比,這兩種架構彼此更爲類似。原因是:

l         它們的特徵是它們用於生成視圖的UI控件類型。

l         架構上幾乎相同。也就是說,在這兩種設計中,AppUi類簡單地“擁有”視圖控件,因此負責直接管理它們。

Avkon視圖切換架構從根本上不同於這兩種方法,它的視圖切換由系統範圍地View服務器來完成。

(1)       基於控件的傳統Symbian OS控件

這些控件總是從CcoeControl直接繼承,用於表示從CcoeControl直接繼承的試圖類的標準術語是“容器”。

關於“CcoeControl”:

可以將CcoeControl認爲是一個空的帳篷。通過繼承這個類,可以創建各種各樣的自定義控件,自定義控件的功能和複雜性只受到程序員能力和想象力的限制。這種靈活性的唯一不利之處是,控件確實類似於一個空帳篷,因爲需要進行許多編碼工作來提供重要的功能。

在處理視圖切換方面,AppUi負責處理用戶發出的視圖切換請求。隨後,AppUi最終的行爲類似於一個巨大的開關,用於根據用戶或系統的輸入來激活或禁止容器。

注意:Container類從CcoeControl派生而來,CcoeControl是所有控件的基類。

在自己的容器類中必須實現從CcoeControl中的四個方法,框架將調用所有這些方法:

l         SizeChanged()允許控件響應控件大小的改變

l         Draw()繪製控件

l         CountComponentControls()返回控件擁有的控件數量

l         ComponentControl()對於容器擁有的每一個控件,框架調用該方法獲取。

 

 

AppUi類中按照如下代碼構造容器:

void ChelloWorldAppUi:::Control()

{

BaseControlL();

IAppContainer=ChelloWorldContainer::NewL(ClientRect());

IAppContainer->SetMopParent(this); //在控件之間建立父子關係,在容器上調用此方法。

AddToStackL(iAppContainer); //Container推入到控件棧頂,例如可以接收鍵事件
}

注意:如果使用這種架構實現帶有多個視圖的應用程序,則通過使用AddToStackL()和RemoveFromStackL()在不同的容器之間切換。

 

(2)       基於對話框的架構

它不同於傳統Symbian OS架構的是,它擁有的控件直接從對話框類家族繼承而來。

對話框的主要優點是:相對於直接從CcoeControl派生而來的控件,它需要較少的開發工作,因爲它們自動管理子控件的佈局。

AppUi類中完成構造和運行:

void CsimpleDlgAppUi::ConstructL()

{

       BaseConstructL();

       IAppDialog=new(ELeave) CsimpleDlgDialog;

       IAppDialog->SetMopParent(this);

       IAppDialog->ExecuteLD(R_SIMPLEDLG_DIALOG);

       AddToStackL(iAppDialog);

}

因爲對話框是無模式的,ExecuteLD()將在調用後立刻返回。必須使用AddToStackL()將對話框添加到控件棧中,因爲無模式的對話框無法自己完成這項工作。

還有,必須在AppUi的析構函數中銷燬該對話框:

CsimpleDlgAppUi::~CsimpleDlgAppUi()

{

if(iAppDialog)

{

       RemoveFromStack(iAppDialog);

       delete iAppDialog;

}
}

 

(3)       Avkon視圖切換架構

比前兩種都複雜,引入另一個類作爲AppUi和容器之間的媒介。另外,AppUi類從CAknViewAppUi繼承,而不是繼承於CaknAppUi

前兩個架構,AppUi直接負責處理視圖切換,它必須管理視圖提交控件的實例化、刪除和顯示。但是,基於CaknView的類在這方面可以很明顯地減少AppUi地任務。

AppUi仍然處理視圖切換的請求,但現在,並不是刪除舊的容器並實例化新的容器,AppUi只需要調用它的其中一個特殊視圖激活函數,如ActiveViewL()。這些特殊的CaknViewAppUi函數向View服務器提交一個激活請求,然後通過基於CaknView的相關類中的激活/禁止成員函數,View服務器顯式地協調當前視圖地禁止和所請求視圖的激活。

 

這種架構所需的一般特性如下:

l         必須設計應用程序,使每個CAknView派生的Avkon視圖擁有一個容器,然後AppUi擁有每個Avkon視圖。

l         必須從CaknViewAppUi派生應用程序的AppUi,而不是從CAknView派生,這是因爲前者提供了註冊、激活和禁止Avkon視圖的方法。

l         必須在View服務器中註冊所有的Avkon視圖。

l         Avkon視圖具有激活/禁止成員函數,View服務器可以直接調用這些函數。必須重寫這些函數,提供從屬容器的正確處理。

View服務器最主要的原則:確定在任意給定時刻,每個應用程序中只有一個Avkon視圖被激活。Avkon視圖通過兩個UIDView服務器唯一性的標誌自己:一個UID用於標誌擁有該視圖的應用程序,另一個UID用於在該應用程序中唯一標誌該視圖。

對於每個基於CAknView的類,需要實現的激活/禁止函數是:DoActiveL()DoDeactivate(),這些函數負責實例化和顯示或者刪除Avkon視圖擁有的UI控件。

View服務器將主動調用DeactivateView(),從而強制遵循每個應用程序中只有一個激活視圖的規則。

 

如何使用Avkon視圖切換架構:

l         使用這種架構時,必須結合使用CaknViewAppUiCAknView類。每個Avkon類都從CAknView派生而來,並且必須包含一個Id()函數,從而系統可以標誌這個類。它也必須實現DoActivateL()和DoDeactivateL()函數。此外,它還必須實現HandleForegroundEventL()、HandleCommandL()和HandleStatusPaneSizeChange()函數,用於處理各種事件

l         用戶請求激活視圖時,View服務器將調用DoActivateL()。該函數的目的是實例化並顯示提交視圖的控件。

注意:在DoDeactivateL()之前可以多次調用DoActivateL()。

l         將要禁止Avkon視圖時,則會調用DoDeactivateL(),該函數負責銷燬它的控件。當應用程序退出時,或者激活相同應用程序的另一個視圖時,將禁止視圖。該函數絕對不能異常退出。

l         只有在激活Avkon視圖時纔會調用HandleForegroundEventL(),即在調用DoActivateL()和DoDeactivateL()之間。當視圖到達前臺時,接收HandleForegroundEventLEtrue,當從前臺移除視圖時,將接收HandleForegroundEventLEfalse。程序員可能希望使用這種方法來設置焦點或控制屏幕更新。

視圖菜單生成一條命令時,調用HandleCommandL(),因爲狀態面板改變而使客戶矩形大小改變時,則調用HandleStatusPaneSizeChange()

 

爲了讓Avkon視圖定義它自己的軟鍵和菜單資源,可以在資源文件(.rss)中創建一個AVKON_VIEW資源,然後將資源ID傳遞到視圖的BaseConstructL()函數中。

通常在AppUi對象的ConstructL()方法中構造應用程序中的所有Avkon視圖。使用AddViewL()在View服務器中註冊這些Avkon視圖,最終通過設置默認的視圖來激活初始視圖,使用方法SetDefaultViewL()

注意:不是由Avkon視圖處理的命令被傳遞到AppUiAppUiHandleCommandL()方法裏,只進行視圖間切換的命令。本地視圖切換或者是應用程序擁有的視圖切換,這些工作都通過引用目標Avkon視圖的UID來執行。

爲了執行外部視圖切換,則需要調用CcoeAppUi::ActivateViewL()函數,提供一個包含目標應用程序UID和目標視圖UIDTVWsViewId。如:

const Tuid KphoneBookUid={0x101f4cce} ;// from PbkUID.h

const Tuid kphoneBookContactViewUid={1};

ActivateViewL(TvwsViewId(KphoneBookUid,KPhoneBookContactViewUid));

注意:如果自己的程序中的某部分視圖能夠被其他程序使用,那麼我們必須通過導出爲頭文件來發布應用程序UID和視圖UID

 

三、選擇適當的應用程序架構

1)使用Avkon視圖切換架構

大多數情況下,這種架構是最佳的架構,但它也具有侷限性,如:視圖切換方案沒有任何內置的方法來保存視圖切換的上下文。也就是說,沒有提供用於定位到前面激活視圖的機制,沒有類似於瀏覽器上後退功能的按鈕的功能。但是DoActivateL()確實收到了前面激活視圖的標誌符,因此可以自定義後退按鈕功能。

2)使用基於控件的傳統symbian OS架構:

l         程序可能只需要一個視圖

l         應用程序具有UI控件,必須保證這些UI控件的私有性。

l         如果是將應用程序從不同的symbian OS平臺移植到series 60

3)使用基於對話框的架構

可以在資源文件中定義控件,讓對話框自動處理佈局和繪畫,這比實現自定義繪畫行爲更爲容易。僅當應用程序的視圖之間沒有任何循環導航路徑時,纔可以對這種應用程序使用“基於對話框”的方法。

發佈了11 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章