MTK中history机制小结

本文介绍了MTK系统中历史(history)机制的工作原理,包括EntryNewScreen的调用过程、history结构体的分析以及GoBackHistory的出栈流程。通过分析历史记录的保存和删除,阐述了在屏幕或应用界面切换时如何管理任务,特别是在资源释放和回调函数的使用上的考虑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MTK的程序开发中,必然会遇到history机制的问题。整体来讲,就是屏幕或应用界面的切换管理问题。在这个方面,MTK的设计是非常好的,在阅读前辈大牛们的总结后,结合自己项目开发中的一些认识,大致分析一下这一套机制。

为什么可以用这样的一个机制呢,不难想象,MTK只是单任务的系统,一个任务一旦开启(激活),那么另一个任务就要退出或到后台运行。这样就保证了任务之间的屏幕切换是单线串联的。想想,如果是多任务的系统,可能有多个任务在同时运行,不停在不同任务之间切换

1EntryNewScreen

对于屏幕有两个非常基本的操作,一个进屏函数(Entry),一个及时退屏函数(exit

每个应用都会用得的一个函数  EntryNewScreen 就是调用mmi_frm_entry_new_screen

mmi_frm_entry_new_screen

{

……

/*主要执行函数 ExecuteCurrExitHandler,保存历史记录和回调退出函数*/

ExecuteCurrExitHandler();

……

/*将新应用作为当前的应用*/

     if ((new_exit_handler != NULL) || (new_entry_handler != NULL))

     {

         mmi_frm_set_generic_exit_handler(new_scrn_id, new_exit_handler, new_entry_handler);

     }

……                            

}

注意:只有当在调用mmi_frm_set_generic_exit_handler后,全局变量currExitScrnID curr_exit_handlercurr_entry_handle才表示当前应用。

 

void ExecuteCurrExitHandler_Ext(void)

{

……

/* 生成历史记录并保存 */

        if (curr_entry_handler)

        {

            mmi_frm_generic_exit_scrn(currExitScrnID, curr_entry_handler);

        }

/*回调当前退出窗口的退出函数*/

        if (curr_exit_handler)

        {

           mmu_frm_execute_scrn_exit_handler = MMI_TRUE;

           curr_exit_handler(curr_exit_scrn_arg_p);

           mmu_frm_execute_scrn_exit_handler = MMI_FALSE;

        }

……

}

 

对于mmi_frm_generic_exit_scrn()函数,其主要调用mmi_frm_add_history()

该函数应该深入研究一下

其中有一个全局变量IsBackHistory,这是一个标志位,标志是否是从GoBackHistory来调用该函数的,以此来决定是否执行后面的保存操作。为什么GoBackHistory会调用到这个地方呢?

其实很明了,EntryNewScreen 会在两种情况下被调用。

1)主动进入一个应用时,产生前一应用的history,此时IsBackHistoryMMI_FALSE,于是就要将前一应用的加入history的堆栈中。

2)通过GoBackHistory回退回来,但是不产生回退前应用的historyIsBackHistory GoBackHistory调用的mmi_frm_go_back_to_history_int函数中被赋值IsBackHistory = MMI_TRUE;

简单来说,IsBackHistory 就是判断 EntryNewScreen 是否要产生history

 

2history

首先分析一下history结构体

typedef struct _historyNode

{

U8  isTab;

/* 窗口*/

    U16 scrnID;

#ifdef __MMI_UI_SMALL_SCREEN_SUPPORT__

    U16 isSmallScreen;

#endif

/* inputBuffer 保存当前编辑框 text 里的内容,比如说短信编辑时,来电话,返回时需要重新显示编辑

*/

U8 *inputBuffer;        /* running text data                   */

 

/* guiBuffer 用于保存当前界面的一些状态信息。比如当前选中的item等等。

  guiBuffer 就是一块内存,可以把它转化为任何结构体,保存信息。

 */

    U8 *guiBuffer;          /* this includes hilite item, input mode & etc.. */

    MemAlloc mallcFuncPtr;  /* keep the memory allocated function */

    MemFree  mfreeFuncPtr;  /* keep the memory freed function */

    mmi_history_node_status_enum status;  

    entry_func_ptr entryFuncPtr;

    void *app_arg;

} historyNode;

 

 

static historyNode historyData[MAX_HISTORY];    /* array of history data */

先大概来理一下history栈的出入栈流程

 

1.(EntryNewScreen)

(1) U8 EntryNewScreen(U16 newscrnID, FuncPtr newExitHandler, FuncPtr newEntryHandler, void *flag);

(2)void ExecuteCurrExitHandler (void);

(3)void ExecuteCurrExitHandler_Ext(void);

(4) void mmi_frm_generic_exit_scrn(U16 scrn_id, entry_func_ptr entry_func_ptr);

(5) MMI_BOOL mmi_frm_add_history(

            U16 scrn_id,                            /* the screen id */

            entry_func_ptr entryFuncPtr,            /* the screen's entry function */

            HistoryGetData getGuiFuncPtr,           /* the function to get GUI data */

            HistoryGetSize getInputBufSizeFuncPtr,  /* the function to get input buffer size */

            HistoryGetData getInputBufFuncPtr,      /* the function to get input buffer */

            MemAlloc mallocFuncPtr,                 /* the function to allocate memory */

            MemFree mfreeFuncPtr,                   /* the function to free memory */

            void* app_arg_p);

(6) static S16 increment(void);

 

2.(GoBackHistory)

(1)void GoBackHistory(void);

(2)static U8 mmi_frm_go_back_to_history_int(U16 scrnid) //historyData

(3)static U8 decrement_current_history_index(void);

 

3SetDelScrnIDCallbackHandler

SetDelScrnIDCallbackHandler函数很精妙,它设置一个回调函数,当这个screen id 被删除的时候,这个回调函数会被调用。当一个应用退出时,需要释放资源的话,最好设置这个函数,不然容易资源泄露。也许这个也可以在exit函数(该屏的退出函数,这样写实方便描述,以下皆同)中来进行操作,但是这样做,有可能需要做比较多的状态保存,来回恢复,更为复杂。因为此处的sreen id的删除是从history stack中删除,与exit函数从逻辑上有区别,执行exit函数时也许并没有从history stack中删除(反而可能是添加),当我返回时还要继续接着上次的进行操作。

1)比如在照相机界面,来了一个短信,欲查看短信,按end键退出到idle,这时该screenid就从history stack中删除,这样就需要在被删除时释放资源。

2)比如编辑短信时,闹钟响起,此时编辑短信的screen Id就加入到history stack中,如果在exit 中释放资源,就会要保存一些信息(如当前的编辑内容),而此时很可能关闭闹钟后就立即回到短信编辑界面,如果资源在exit释放了,那么此时就要进行恢复,显得很麻烦,所以在history stack中删除sreen id时来进行回调操作就显得较为方便了。

 

to be continued

 

ps:这是我在方案公司实习过程中学习mtk的简单小结,其中参考了很多技术大牛、MTK前辈们的一些总结博文,在此对他们表示崇敬和谢意。

 

参考文献及博文:

[1] http://blog.youkuaiyun.com/yanwuxufeng/archive/2010/08/15/5814655.aspx

[2] http://blog.youkuaiyun.com/blogercn

[3] MTK专题集(讲述MTK各个重要功能模块).doc

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值