touchgfx的工作机制
一.MVP软件架构
MVP的全称为Model-View-Presenter
Model: 就是数据部分,在整个touchgfx应用中,只有一个Model类实例对象,它为所有的Screen屏幕界面服务,可以理解成是一个全局变量区,同时它还负责和后端系统通信
View: 就是UI界面部分,对应于View类,在整个touchgfx应用中,可以存在多个View实例对象,一个View实例对象其实就是一个Screen屏幕界面
Presenter: 就是项目的业务逻辑部分,相当于是一个主持人,负责在Model和View之间进行数据中转
注: 每一个Screen屏幕界面,都会有一个专有的View类和专有的Presenter类与之对应,但是Model类是所有屏幕界面共有的
二.View类
1.构造函数: 主要是做一些成员变量的初始化
2.setupScreen : 主要是做一些UI控件的属性初始化
3.tearDownScreen: 做一些资源释放
4.虚构函数: 做一些资源释放
上面四个函数也可以说是一个Screen屏幕界面的生命周期,由从上到下的顺序被系统调用,而且都只会被调用一次
三.Model类
1.构造函数: 主要是做一些成员变量的初始化
2.Tick函数: 每隔一个tick周期就会被调用一次,而一个tick周期其实就是一个屏幕刷新周期,取决于你的LCD像素时钟,一般在20ms左右,在这里主要负责轮询后端系统的事件
四.Presenter类
1.构造函数
2.activate
3.deactivate
五.内存管理机制
这里的内存指的是微处理器内部的ram
touchgfx中的控件对象的内存分配全部都是在内部ram中的,而且都是分配在几个私有的大数组中
Block stBlocks[NUMBER_OF_ELEMENTS];
因此touchgfx的内存分配是在程序编译时就完成了的,而不是在程序运行时动态分配的,
因此内存消耗的大小是确定可控的,不会出现运行时的内存泄露问题
内存管理的细节由FontendHeap单例类(在TouchGFX\gui\include\gui\common目录下)来描述,总内存消耗由以下几部分构成:
touchgfx::Partition< CombinedPresenterTypes, 1 > presenters;
touchgfx::Partition< CombinedViewTypes, 1 > views;
touchgfx::Partition< CombinedTransitionTypes, 1 > transitions;//屏幕切换动画
Model model;
FrontendApplication app;
举例:
1.presenters所分配的内存空间大小等于界面中内存消耗最大的那一个Presenter,而不是所有的Presenter内存消耗的总和,然后所有的Presenter共享同一个presenters内存区域,即分时复用
2.views所分配的内存空间大小等于界面中内存消耗最大的那一个View,而不是所有的View内存消耗的总和,然后所有的View共享同一个views内存区域,即分时复用
五)启动流程
1)void touchgfx_init()
void touchgfx_init()
{
//挂载图片数据库
Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(), BitmapDatabase::getInstanceSize());
//挂载文本服务类
TypedText::registerTexts(&texts);
//设置语言
Texts::setLanguage(0);
//设置字体提供器
FontManager::setFontProvider(&fontProvider);
//创建内存管理
FrontendHeap& heap = FrontendHeap::getInstance();
/*
* we need to obtain the reference above to initialize the frontend heap.
*/
//避免警告
(void)heap;
/*
* Initialize TouchGFX
*/
hal.initialize();
}
2)
static FrontendHeap& getInstance()
{
static FrontendHeap instance;
return instance;
}
3)跳转到启动界面
FrontendHeap() : FrontendHeapBase(presenters, views, transitions, app),
app(model, *this)
{
gotoStartScreen(app);
}
4)
virtual void gotoStartScreen(FrontendApplication& app)
{
app.gotostartScreenScreenNoTransition();
}
5)设置回调函数,此时是没有进行界面跳转的
void FrontendApplicationBase::gotostartScreenScreenNoTransition()
{
transitionCallback = touchgfx::Callback<FrontendApplicationBase>(this, &FrontendApplicationBase::gotostartScreenScreenNoTransitionImpl);
pendingScreenTransitionCallback = &transitionCallback;
}
6)这个地方才是真正的界面跳转
void FrontendApplicationBase::gotostartScreenScreenNoTransitionImpl()
{
touchgfx::makeTransition<startScreenView, startScreenPresenter, touchgfx::NoTransition, Model >(¤tScreen, ¤tPresenter, frontendHeap, ¤tTransition, &model);
}