symbian的UI/引擎結構
*Symbian應用程式可以分為:
- UI(視圖)
·將應用程式的資料在螢幕上顯示給使用者
— 引擎(模型)
·處理應用程式資料
不同的應用程式結構
*傳統SymbianOS
*基於對話方塊
*基於Avkon視圖
傳統結構框圖
應用程式類
*第一個需要建立的對象
*必須重寫:
- CreateDocumentL()建立文檔對象
- AppDIIUid()返回應用程式的唯一ID(如UID3)
class CMyAppApp::public CAknApplication
{
private:
......來自基類的函數
CApaDocument* CreateDocumentL();
TUid AppDIIUid() const;
};
文檔類
*通常將應用程式的資料存至檔案或從檔案載入資料
- 在許多應用程式中,該功能是不需要的
- 在S60中,該功能預設是無效的
*建構函式必須將應用程式物件的引用傳給CAknDocument
*必須重寫CreateAppUiL()來建立AppUi
class CMyAppDocument:public CAknDocument
{
public:
static CMyAppDocument* NewL(CEikApplication & aApp);
virtual ~CMyAppDocument();
private:
CMyAppDocument(CEikApplication& aApp);
void ConstructL();
CEikAppUi* CreateAppUiL();
};
應用程式UI類
*處理應用程式中的命令(針對菜單)和事件(針對按鍵)
- 重寫基類中的虛函數
*建立和擁有Container對象
*二階段構造不需要通過NewL()來完成
class CMyAppAppUi:public CAknAppUi
{
public:
void ConstructL();
~CMyAppAppUi();
CMyAppAppUi();
private:
void DynInitMenuPaneL(IInt aResourceId,CEikMenuPane* aMenuPane);……主要是菜單的動態顯示:菜單的選項可以跟著程式的狀態動態地地調整。
void HandleCommandL(TInt aCommand);
private:
CMyAppContainer* iAppContainer;
};
容器類
*建立和擁有控制項或容器
*處理與命令和事件有關的繪圖操作
- 重寫基類中的虛函數
class CMyAppContainer:public CCoeControl
{
public:
static CMyAppContainer* NewL(const TRect& aRect);
~CMyAppContainer();
private:
CMyAppContainer();
void ConstructL(const TRect& aRect);
private:.....來自基類的函數
void SizeChanged();
TInt CountComponentControls() const;反回組件數目
void Draw(const TRect& aRect) const;
private:^成員變數
CEikLabel* iLabel1;
CEikLabel* iLabel2;
};
優點和不足
*優點
- 十分靈活地實現應用程式UI的建立
- 開發人員可以創造和設計自己的UI結構
*缺點
- 沒有系統提供的視圖管理系統,不方便複雜的應用程式的實現
基於對話方塊的結構框圖
基於對話方塊的結構
*使用對話方塊作為主要視圖(一種特殊的容器)
*多頁對話方塊可以代表多重視圖
- AVKON提供了自動的狀態空格標籤操作
*優點
- 可以在資源檔中修改內容和版面,不需要重新編譯C++代碼
*缺點
- 嵌套對話方塊如果沒有認真書寫代碼將佔有大量的棧空間
Avkon視圖結構
Avkon視圖結構介紹
*視圖代表應用程式的顯示頁面
- 應用程式將“視圖”註冊到視圖伺服器
- 應用程式根據事件響應來啟用/去啟用視圖伺服器中的視圖
- 某個時刻,在運行著的程式中只能有一個視圖處於啟用狀態
*允許應用程式發送和接收請求來顯示資料的某個特殊視圖
*該結構可以認為是一種訊息傳遞系統
*通過UI進行的導航是基於進行中的任務
優點
*視圖的資料和功能壓縮到視圖對象,然後各個視圖進行自己的啟用/去啟用操作
*該結構更加物件導向,更加適合需要修改的情況
*視圖的外部伺服器管理意味著應用程式要發起請求來切換其他應用程式的視圖
- 使得共用某個功能的應用程式之間的依賴性增強
- 降低了單個應用程式的複雜性
- 使應用程式更加高效
缺點
*視圖結構架構是有限制的
*並不能用於所有情況
*只適用於不將視圖提供給外部應用程式使用,或可以處理外部程式中斷的應用程式
Avkon視圖中的AppUi類
CAknViewAppUi
*所有基於視圖結構的應用程式都必須由該類繼承
*建立和管理應用程式視圖,由CAknAppUi繼承而來
*將繪圖和基於螢幕的互動操作交予視圖
*負責視圖之間的切換
AppUi類樣本
*視圖通過AknViewAppUi衍生類別的ConstructL()來建立
void CMyAppUi::ConstructL()
{
BaseConstrcutL();
CMyView1* view1 = CMyView1::NewLC();...建立視圖1
AddView(view1);....將所有權轉移給CMyAppUi
CleanupStack::Pop();
CMyView2* view2 = CMyView2::NewLC();
AddViewL(view2);
CleanupStack::Pop();
...設定預設視圖為視圖1
ActivateLocalViewL(view1->Id())
}
Avkon視圖類
CAknView
*處理視圖中的命令和事件
*每個視圖都相當於一個小的應用程式UI
*建立它自己的控制項類,從CCoeContorl繼承而來
Avkon視圖類樣本
*CAknView-衍生類別定義:
class CMyView1:public CAknView
{
public:...建構函式和解構函式
static CMyView1* NewL();
static CMyView1* NewLC();
virtual ~CMyView1();
public:..from CAknView
TUid Id() const ...返回視圖id
void DoActivateL(const TVwsViewId& aPrevViewId,TUid aCustomMessageId, const TDesC8& aCustomMessage);
void DoActivete();
void HandleForegroundEventL(TBool aForeground);
void HandleCommandL(TInt aCommand);
void HandleStatusPaneSizeChange();
private:
CMyView1();...執行第一階段建構函式
void ConstructL(); ....執行第二階段建構函式
private:...成員變數
CMyContainer1 * iMyContainer1;....用於該視力的窗器
};
Avkon視圖類函數
*構造
— NewL()和NewLC()進行二階段構造
- 都調用私人的ConstructL()
調用CAknView::BaseConstructL()傳遞視圖的資源ID
void CMyView1::ConstructL()
{
BaseConstructL(R_MY_VIEW_1);
}
*析構
- 完成和DoDeactivate()相同的功能
*Ui特有的構造/析構代碼應位於DoActiveateL()和DoDeactive(),因為在一個時刻只有一個視圖處於啟用狀態
*應該重寫CAknView的
- Id()
@返回視圖唯一ID,類型為TUid
@該ID由開發人員在視圖的標頭檔中定義
- DoAcitvateL(..)
@在啟用視圖時調用
@作為部分請求,可以接受訊息參數
@建立視圖的視窗並把它添加到棧中
@必須處理當視圖已經處於啟用狀態時的調用
- DoDeactive()
@在去啟用視圖時調用(如退出應用程式或應用程式的其他視圖被啟用時)
@刪除視力的容器並把它從應用程式UI棧中移去
@該函數絕對不可以忽略
- HandleForegroudEventL(TBool aForeground)
@用於設定焦點或控制螢幕更新
@只在視圖處於啟用狀態時調用
@只在前景狀態變化時調用
@aForeground取值
- ETrue當移至前景時
- EFalse當從前景移開時
-HandleCommandL()
@處理菜單/軟鍵的命令
-HandaleStatusPaneSizeChange()
@當因為狀態空格的改變導致用戶端矩形尺寸發生變化時調用
Avkon視圖資源
*每個視圖都有相關聯的資源,使得視圖可以有自己的菜單和/或命令按鈕數組(CBA)
*AVKON_VIEW資源提供
- 帶有菜單的視圖
- 帶有CBA的視圖
*樣本
RESOURCE AVKON_VIEW r_my_view_1
{
menubar = r_my_menubar_1;
cba = R_AVKON_SOFTKEYS_OPTIONS_BACK;
}
切換視圖
*由CAknViewAppUi根據使用者命令的響應來處理
*本地視力切換
- 在同一個應用程式裡啟用其他的視圖,去啟用當前視圖
- 通過指定目標視圖的UID來實現
- CAknViewAppUi::ActivateLocalViewL(TUid aViewId)
*遠程視圖切換
- 啟用其他應用程式的視圖
- 通過指定目標應用程式的UID和目標視圖的UID來實現
- CCoeAppUi::ActiveViewL(const TVwsView& aViewId)