Larena3 0架构与关键技术
-
Upload
hiklhz -
Category
Technology
-
view
291 -
download
0
description
Transcript of Larena3 0架构与关键技术
23/4/12
LARENA3.0 架构与关键技术联芯科技
总体架构
Glib/GObject
Glib :提供基本数据结构和函数库。
Gobject :提供面向对象的支持。版本: 2.6.6 (裁剪)。
单链表 双链表 哈希表 数组 队列 …
内存分配 字符串 log …
GObject 类概念
typedef struct _GokuApp GokuApp;typedef struct _GokuAppClass GokuAppClass;
struct _GokuApp{ GObject parent_instance;};
struct _GokuAppClass{ GObjectClass parent_class; gboolean (*on_start)(GokuApp *app); gboolean (*on_pause)(GokuApp *app); gboolean (*on_resume)(GokuApp *app); gboolean (*on_stop)(GokuApp *app); const gchar * (*get_theme_name)(GokuApp *app); const gchar * (*get_language_name)(GokuApp *app); void (*on_activity_type_reg)(GokuApp *app); GType (*get_facade_type)(GokuApp *app);};
实例结构体实例结构体
类结构体类结构体
GObject 类继承
typedef struct _GokuCallApp GokuCallApp;typedef struct _GokuCallAppClass GokuCallAppClass;
struct _GokuCallApp{ GokuApp parent;};
struct _GokuCallAppClass{ GokuAppClass parent_class;};
static void goku_call_app_init(GokuCallApp *call){
}
static void goku_call_app_class_init(GokuCallAppClass *klass){ GObjectClass *object_class = G_OBJECT_CLASS(klass); GokuAppClass *app_class = GOKU_APP_CLASS(klass);
object_class->finalize = goku_call_app_finalize;
app_class->on_start = goku_call_app_on_start; app_class->on_stop = goku_call_app_on_stop; app_class->on_activity_type_reg = goku_call_app_register_acitivity_type; app_class->get_facade_type = goku_call_app_get_facade_type;}
static void goku_call_app_init(GokuCallApp *call){
}
static void goku_call_app_class_init(GokuCallAppClass *klass){ GObjectClass *object_class = G_OBJECT_CLASS(klass); GokuAppClass *app_class = GOKU_APP_CLASS(klass);
object_class->finalize = goku_call_app_finalize;
app_class->on_start = goku_call_app_on_start; app_class->on_stop = goku_call_app_on_stop; app_class->on_activity_type_reg = goku_call_app_register_acitivity_type; app_class->get_facade_type = goku_call_app_get_facade_type;}
Gobject 对象宏
宏#define GOKU_TYPE_CALL (goku_call_get_type())#define GOKU_CALL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GOKU_TYPE_CALL, GokuCall))#define GOKU_CALL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GOKU_TYPE_CALL, GokuCallClass))#define GOKU_IS_CALL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GOKU_TYPE_CALL))#define GOKU_IS_CALL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GOKU_TYPE_CALL))#define GOKU_CALL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GOKU_TYPE_CALL, GokuCallClass))
G_DEFINE_TYPE(GokuCall, goku_call, GOKU_TYPE_APP)
goku_call_get_type();goku_call_init(GokuCall *call);goku_call_class_init(GokuCallClass *klass);
应用框架
GokuApp
GokuActivity GokuCommand
GokuFacade
GokuService
GokuApp :负责应用启动、恢复、暂停、结束、主题、语言、组件类型注册。GokuFacade : 负责注册 Command 、 Service 。MM GokuService :负责域逻辑处理。 VV GokuActivity : 呈现 UI ,负责处理窗口、控件消息;创建菜单、对话框。CC GokuCommand :负责业务逻辑处理。
GokuApp 类
struct _GokuAppClass{ GObjectClass parent_class;
gboolean (*on_start)(GokuApp *app);
gboolean (*on_pause)(GokuApp *app);
gboolean (*on_resume)(GokuApp *app);
gboolean (*on_stop)(GokuApp *app);
const gchar *(*get_theme_name)(GokuApp *app);
const gchar *(*get_language_name)(GokuApp *app);
void (*on_activity_type_reg)(GokuApp *app);
GType (*get_facade_type)(GokuApp *app);};
GokuActivity 类
与用户交互的对象负责建立窗口及子窗口负责 UI消息的处理负责旋屏的处理
GokuActivity 创建
static void goku_demo_activity_class_init(GokuDemoActivityClass *klass){
GOKU_ACTIVITY_CLASS(klass)->on_create = goku_demo_activity_on_create;}
void goku_demo_activity_on_create(GokuActivity *activity, GokuIntent * intent ){
HWND ctrl_static = HWND_INVALID; const gchar *text = resources_get_string_by_id(IDS_STATIC);
goku_activity_set_layout_id(activity, IDL_LAYOUT_DEMO);
ctrl_static = goku_activity_get_wnd_by_id(activity, IDC_STATIC_TEXT);control_static_set_text(ctrl_static, text);
}
demo_resource.h
#define IDS_STATIC 0x00000001#define IDS_SKB_BACK 0x00000002#define IDL_LAYOUT_DEMO 0x00000003#define IDL_POPMENU 0x00000004#define IDC_STATIC_TEXT 0x00000005#define IDC_TITLEBAR 0x00000006#define IDS_DEMO 0x00000007#define IDF_IMAGE_DEMO 0x00000008
resource.hresource.h是由是由 UI DesignerUI Designer自动生成的头文件自动生成的头文件IDL_ IDL_ 表示布局文件索引值表示布局文件索引值IDC_ IDC_ 表示控件索引值表示控件索引值IDS_ IDS_ 表示字符串索引值表示字符串索引值IDF_ IDF_ 表示文件路径索引值表示文件路径索引值
layout.xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?><LAYOUTWINDOW FillColor="255 255 255" Id="IDL_LAYOUT_DEMO">
<LINEARLAYOUT Name="ID_LINEARLAYOUT_TITLEBAR_CONTACT_ALL" Orientation="Vertical"><TITLEBAR Name="IDC_TITLEBAR" Height="38" LayoutId="IDL_SYSTEM_TITLEBAR_SIMPLE"/><STATIC Name="IDC_STATIC_TEXT" AlignHorizontal="Center" FillColor="255 255 255">
<TEXT FontSize="20" AlignHorizontal="Center" AlignVertical="Center"/></STATIC>
</LINEARLAYOUT></LAYOUTWINDOW>
Activity 与 Layout
Layout.xml
ActivityActivity 1 - 11 - 1
Window ProcWindow Proc
1 - 11 - 1
IDID
goku_activity_set_layout_id(activity, IDL_DIALER);goku_activity_set_layout_id(activity, IDL_DIALER);
GokuActivity 注册
goku_demo_app.c goku_demo_app.c 片段片段
static void goku_demo_class_init(GokuDemoAppClass *klass){ GokuAppClass *app_class = GOKU_APP_CLASS(klass);
app_class->on_activity_type_reg = goku_demo_register_acitivity_type;}
static void goku_demo_register_acitivity_type(GokuApp *app){
GOKU_TYPE_DEMO_APP_ACTIVITY; //goku_demo_app_activity_get_type();}
goku_demo_app.c goku_demo_app.c 片段片段
static void goku_demo_class_init(GokuDemoAppClass *klass){ GokuAppClass *app_class = GOKU_APP_CLASS(klass);
app_class->on_activity_type_reg = goku_demo_register_acitivity_type;}
static void goku_demo_register_acitivity_type(GokuApp *app){
GOKU_TYPE_DEMO_APP_ACTIVITY; //goku_demo_app_activity_get_type();}
Notification 组件间交互
goku_call_notification.hgoku_call_notification.h
#define NOTI_START_SERVICE "NOTIFY_START_SERVICE"#define NOTI_STOP_SERVICE "NOTIFY_STOP_SERVICE“
一个一个 NotificationNotification用一个字符串表示用一个字符串表示只在应用线程内有效只在应用线程内有效ActivityActivity 接收或触发一个接收或触发一个 CommandCommand
Notification 发送与接收
void goku_mvc_send_notification(const gchar *notification_name);void goku_mvc_send_notification_with_body(const gchar *notification_name, gconstpointer body);
goku_call_activity.c goku_call_activity.c 片段片段
void goku_call_activity_handle_notification( GokuIMediator *imediator, GokuINotification *inotification ){ const gchar *noti_name = goku_inotification_get_name(inotification);
if (g_str_equal(noti_name, NOTI_CALL_RETRIEVED_IND)){
…}else if (g_str_equal(noti_name, NOTI_CALL_TRANSFER_IND)){
…}
}
goku_call_activity.c goku_call_activity.c 片段片段
void goku_call_activity_handle_notification( GokuIMediator *imediator, GokuINotification *inotification ){ const gchar *noti_name = goku_inotification_get_name(inotification);
if (g_str_equal(noti_name, NOTI_CALL_RETRIEVED_IND)){
…}else if (g_str_equal(noti_name, NOTI_CALL_TRANSFER_IND)){
…}
}
Activity 中注册感兴趣的 Notification
void goku_call_activity_imediator_interface_init( GokuIMediatorClass *iface ){
iface->list_notification_interests = goku_call_activity_list_notification_interests;iface->handle_notification = goku_call_activity_handle_notification;
}
GList * goku_call_activity_list_notification_interests(GokuIMediator *imediator){ GList * noti_list = NULL; noti_list = g_list_append(list, NOTI_CALL_RETRIEVED_IND); noti_list = g_list_append(list, NOTI_CALL_TRANSFER_IND); return noti_list;}
Command 类
struct _GokuSimpleCommandClass{
GokuNotifierClass parent_class;
void (*execute)(GokuSimpleCommand *icommand, GokuINotification *inotification);};
由由 NotificationNotification 触发触发处理复杂的操作或业务逻辑处理复杂的操作或业务逻辑降低降低 ActivityActivity 与与 ServiceService之间的耦合之间的耦合在在 NotificationNotification 发生后生成实例,发生后生成实例, executeexecute函数返回后被实例销毁函数返回后被实例销毁
Command 与 Notification
ActivityActivity
FacadeFacade
CommandCommand
ServiceService
NotificationNotification ActivityActivity
CommandCommand
ServiceServiceNotificationNotification
ExecuteExecute
NotificationNotification
AnyAny
NotificationNotification
NotificationNotification
Command 类注册
static void goku_call_facade_initialize_controller(GokuFacade *facade){ GokuIFacade *ifacade = GOKU_IFACADE(facade); GOKU_FACADE_CLASS(goku_call_facade_parent_class)->initialize_controller(facade);
goku_ifacade_register_command(ifacade , NOTI_INCOMING_CALL, GOKU_TYPE_INCOMING_CALL_COMMAND); goku_ifacade_register_command(ifacade , NOTI_DIAL, GOKU_TYPE_CALL_DIAL_COMMAND); goku_ifacade_register_command(ifacade , NOTI_ANSWER, GOKU_TYPE_CALL_ANSWER_COMMAND);}
由由 GokuFacadeGokuFacade 类注册类注册NotificationNotification 与与 CommandCommand 的的 TypeType对应对应多个多个 NotificationNotification可以对应一种可以对应一种 CommandCommand
GokuService 类
管理应用数据负责域逻辑与 Larena Platform组件交互接收通道消息只有调用 goku_start_service后才能接收消息GokuService通过抛出 Notification通知使用者不在MVC架构中使用者可使用 CALLBACK方式代替 Notification
GokuService 通道消息处理
注册感兴趣的消息注册感兴趣的消息static GList * goku_call_service_get_interested_msgs(GokuService *service){ GList * msgs = NULL; msgs = g_list_append(msgs, GINT_TO_POINTER(TPM_CALL_DIAL_RESULT)); msgs = g_list_append(msgs, GINT_TO_POINTER(TPM_CALL_ANSWER_RESULT)); msgs = g_list_append(msgs, GINT_TO_POINTER(TPM_CALL_REMOTE_HANGUP)); msgs = g_list_append(msgs, GINT_TO_POINTER(TPM_CALL_PROGRESS_IND));
return msgs;}
处理消息处理消息static void goku_call_service_on_msg(GokuService * service, gint msg, gconstpointer data, guint size){
switch (msg){case TPM_CALL_DIAL_RESULT:
… break; }}
GokuService 注册和使用
创建和注册创建和注册 ServiceServicevoid goku_call_facade_initialize_model( GokuFacade *facade ){ GokuCallService *call_service;
GOKU_FACADE_CLASS(goku_call_facade_parent_class)->initialize_model(facade);
call_service = goku_call_service_new(); goku_ifacade_register_proxy(GOKU_IFACADE(facade), GOKU_IPROXY(call_service )); ….}
在在 CommandCommand中使用中使用 FacadeFacadestatic void goku_call_dial_command_execute(GokuSimpleCommand *icommand, GokuINotification *inotification){ GokuCallService * service = GOKU_CALL_SERVICE(goku_mvc_retrieve_proxy(GOKU_CALL_SERVICE_NAME)); … goku_call_service_create_call(service, number, NULL, 0);}
GokuFacade
注册 Notification 和 Command 的对应关系注册 Service
框架中提供的 Service
通过通过 serviceservice名称创建名称创建contact_service = goku_service_create(GOKU_CONTACT_SERVICE_NAME);
在应用线程中执行在应用线程中执行可以使用可以使用 ServiceService提供的提供的 APIAPI可以处理可以处理 ServiceService抛出的抛出的 NotificationNotification
Intent
Intent类似于 NotificationIntent将由系统选择最合适的应用程序处理向系统表达你的 Intent(意图)查看图片、打电话都是意图框架定义了一系列 Intent
Intent
拨打电话拨打电话 IntentIntent GokuIntent *intent = goku_intent_new_from_action(“GokuIntentActionCall”); goku_value_set_put_string(intent->extras, "number", “13999999999”); goku_activity_start_activity(activity, intent);
manifest.xml
每个应用都有一个manifest.xml文件manifest声明应用类名称 (GokuApp结构体 )、应用 ID、应用名称、应用图标manifest声明 activity类名称, activity图标、 activity处理的 Intent
call application manifest.xmlcall application manifest.xml<?xml version="1.0" encoding="utf-8"?><application class="GokuCall" id="0x6303" name="IDS_VOICE_CALL" res="applications/call" small_icon ="call.png">
<activity class="GokuCallActivity" name="IDS_VOICE_CALL" action="GokuIntentActionCall" launch_mode="singleTask" small_icon ="call.png"/></application>
Manager
ManagerManager是一个开机时启动,常驻后台的应用是一个开机时启动,常驻后台的应用ManagerManager一般没有界面,一般没有界面, Notification ManagerNotification Manager 除外除外ManagerManager一般会发布一般会发布 ServiceService
Manager 中的 C/S 通信模型
GokuService
GokuServerService
on_client_connect()on_client_disconnect()on_client_request()
GokuClientService
on_connected()on_disconnected()on_receive()
GokuServerServiceGokuServerService 和和 GokuClientServiceGokuClientService 都是一种都是一种 ServiceServiceGokuServerServiceGokuServerService 运行在运行在 ManagerManager线程中线程中GokuClientServiceGokuClientService 运行在运行在 Application/ManagerApplication/Manager 线程中线程中GokuClientServiceGokuClientService 提供提供 APIAPIGokuServerServiceGokuServerService 和和 GokuClientServiceGokuClientService 都可以抛出都可以抛出 NotificationNotification
Manager 的使用
Program Application Thread Package Manager Thread
ActivityActivity CommandCommand GokuPackageService
GokuPackageService
PacageMgr ServerServicePacageMgr
ServerServicePackageMgr
InstallCommandPackageMgr
InstallCommandGokuPackag
eServiceGokuPackag
eService
2: Install Package
3: Install Message
4: Notification
5: Install Result
7: Notification
1: Notification
6: Install Result
HomeScreen Thread
Activity Manager
Activity ManagerActivity
Manager
Home ScreenHome Screen DialerDialer
dialer activitydialer activity
CallCall
call activitycall activity
TaskTask
main menu activitymain menu activity
Call IntentCall Intent
DialerIntentDialerIntent
Resources
File SystemFile System
LayoutThemeImageString
LayoutThemeImageString
LayoutThemeImageString
LayoutThemeImageString
ResourcesResources
APP1APP1 APP2APP2
ID
BITMAP* resources_get_image_by_id(UINT32 id);CONST CHAR* resources_get_string_by_id(UINT32 id);
BITMAP* resources_get_image_by_id(UINT32 id);CONST CHAR* resources_get_string_by_id(UINT32 id);
资源智能选取
240x320240x320 320x480320x480
ResourcesResources
资源文件夹
资源文件夹
资源文件夹
资源文件夹
imageimage
image-320X480image-320X480
layoutlayout
layout-320X480layout-320X480
layout-240X320layout-240X320
240x320 landscape 240x320
landscape
layout-landscape-240X320
layout-landscape-240X320
image-landscapeimage-landscape
LCDInfoLCDInfo
Theme
Theme :描绘所有支持的控件的主题信息描绘所有支持的控件的主题信息
<EDIT BgType="ImageFile" SizingType="Stretch" SizingMargins="0 2 0 2" <EDIT BgType="ImageFile" SizingType="Stretch" SizingMargins="0 2 0 2" ImageFile="image/edit.png" ImageCount="2" ImageLayout="Vertical" ImageFile="image/edit.png" ImageCount="2" ImageLayout="Vertical" FillColor="255 255 255" BorderColor="0 0 0" BorderSize="" FillColor="255 255 255" BorderColor="0 0 0" BorderSize="" ContentMargins="4 0 0 0" />ContentMargins="4 0 0 0" />
布局
LinearLayout线性布局所有对象成行或列,即所有对象穿成串。TableLayout将界面元素按行、列排列。一个表布局含有几个 TableRow 对象,每个 TableRow 即是一个水平方向的线性布局。
AbsoluteLayout窗口元素按照指定的确切( x, y )坐标,并把自己显示在该位置。RelativeLayout允许窗口元素根据其他元素的相对位置,或者是和父亲布局的相对位置来确定自身位置。
以上四种布局可以嵌套使用,宽度、高度和各种间距均可采用相对值(即百分比)以达到开发者快速开发以及绝对适配屏幕分辨率的要求。
线性布局
相对布局
表布局
表布局
支持横屏旋转及分辨率改变
240X400400X240
布局嵌套及分辨率适配
布局嵌套及分辨率适配
控件
控件响应
gint goku_demo_activity_proc(GokuActivity *activity, HWND hWnd, gint msg, guint wParam, gulong lParam){ switch (msg) { case MSG_KEYDOWN: { switch ( wParam )
{ case KEY_RSK:
goku_activity_finish_activity(activity); break;
case KEY_LSK: goku_activity_popmenu_create(activity, IDL_POPMENU, GOKU_POPMENU_FROM_BOTTOM); break;
} } break; }
return DefaultMainWinProc(hWnd, msg, wParam, lParam);}
在 Activity 中重载 on_layout_wnd_procon_layout_wnd_proc 函数
activity_class->on_layout_wnd_proc = goku_demo_activity_proc;
LOG 与调试
Glib 提供丰富的 LOG 接口,包括对象类型判断、断言、返回判断;可重定向的 LOG 输出,控制台、文件、网络;可按应用进行 LOG 分类输出对象泄漏检测,在应用退出时可检测应用中的泄漏,并输出分配调用栈;
谢谢您的关注