MTK窗口历史管理

这一阶段一直在做MTK平台的开发,所以今天就准备了一些MTK的东西,与大家分享,今天主要的内容是
MTK的窗口历史管理。
MTK的窗口是由函数
U8 EntryNewScreen(U16 newscrnID, FuncPtr newExitHandler, FuncPtr newEntryHandler, void *flag)
来实现的。
该函数中参数的意义如下:
newscrID:新窗口的ID,每个窗口都有全局唯一的序号,该序号被定义于
newexithandler:新窗口的退出函数执行句柄
newentryhandler:新窗口的进入函数执行句柄,如果不为空,将会被系统自动加入窗口历史中
flag:不是很明白,碰到的基本都是NULL或者(void *)1;
NULL是采用普通方式进入新窗口,(void*)1则是全屏方式
其实还有
#define MMI_SMALL_SCREEN    ((void*)2)   /* *RESERVED* identify small-screen APP in EntryNewScreen() */
#define MMI_TAB_PAGE        ((void*)3)
但是我没碰见过,所以此处不予考虑。

用户调用该函数后,将会先调用
    currTopScrnID = newscrID
    
    执行ExecuteCurrExitHandler
    执行
    而此时currEntryFuncPtr仍旧保存在原来屏幕的入口函数,它会去执行
    GenericExitScreen(currExitScrnID, currEntryFuncPtr);
    内部的核心代码正是
        history h;
    U16 nHistory = 0;

    h.scrnID = scrnID;
    h.entryFuncPtr = entryFuncPtr;
    mmi_ucs2cpy((S8*) h.inputBuffer, (S8*) & nHistory);
    GetCategoryHistory(h.guiBuffer);
    AddHistory(h);
    而AddHistory完成了压栈的过程。
    那么历史记录又是如何保存的呢?我们可以去看history.c文件,可见Addhistory实际的工作如下:
    if (IsBackHistory != MMI_TRUE)//如果是进入窗口那么它是false,如果是用户回退,那么它是true
    {

        increment();//使得当前堆栈栈顶指针加1
        /* 3. Store History to History Data Structure */
        memset(&historyData[currHistoryIndex], 0, sizeof(historyNode));//初始化新结点
        historyData[currHistoryIndex].scrnID = addHistory->scrnID;//往新结点填入窗口ID
        historyData[currHistoryIndex].entryFuncPtr = addHistory->entryFuncPtr;//往新结点填入入口函数指针
    #ifdef __MMI_UI_SMALL_SCREEN_SUPPORT__
        historyData[currHistoryIndex].isSmallScreen = (U16) small_history_node;
    #endif 
        length = mmi_ucs2strlen((PS8) addHistory->inputBuffer);
        MMI_ASSERT(length * ENCODING_LENGTH + ENCODING_LENGTH <= MAX_INPUT_BUFFER);
        if (length)
        {
            historyData[currHistoryIndex].inputBuffer = OslMalloc(length * ENCODING_LENGTH + ENCODING_LENGTH);
            mmi_ucs2cpy((PS8) historyData[currHistoryIndex].inputBuffer, (PS8) addHistory->inputBuffer);
        }
        historyData[currHistoryIndex].guiBuffer = OslMalloc(MAX_GUI_BUFFER);
        memcpy(historyData[currHistoryIndex].guiBuffer, addHistory->guiBuffer, MAX_GUI_BUFFER);
    }
#ifdef __MMI_UI_SMALL_SCREEN_SUPPORT__
    small_history_node = 0;
#endif 
    IsBackHistory = MMI_FALSE;
    
    在这里,大家可能跟我一样,都会很疑惑为什么系统没有去保存退出函数,下面的gobackhistory的分析我们就会明白。
    
    完成记录之后,它会去执行currExitFuncPtr,使得退出前一个窗口。
    最后SetGenericExitHandler会将新窗口的id,入口函数,退出函数都设置为curr的变量上。
    
    下面我们来看退出函数Gobackhistory,我们这里为方便起见,抓了一组由菜单退到mainmenu的过程的堆栈情况:
    ExecuteCurrExitHandler_Ext() line 985
ExecuteCurrExitHandler() line 763
EntryNewScreen(unsigned short 1502, void (void)* 0x0083ac45 exit_main_menu(void), void (void)* 0x00000000, void * 0x00000001) line 878
goto_main_menu() line 1581 + 19 bytes
ExecutePopHistory() line 1511 + 18 bytes
GoBackHistory() line 1227

可以看见,在gobackhistory里面,我们会去做堆栈的退栈操作,褪出来的是我们的入口函数,也就是说这个入口函数就是goto_main_menu,所以这
就相当于再次进入了mainmenu,而这时候的这些参数(例如退出函数)是具备的。

以上讨论的就是整体的history管理。有空我会继续对退出部分也作出细化。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值