iOS上的FireMonkey中的ShowMessage()行为

时间:2018-04-27 21:04:58

标签: firemonkey c++builder-10.2-tokyo

我有一个简单的FMX多设备C ++应用程序。该应用程序有1个表单,没有别的。在Form的OnShow事件中,我启动了一个名为StartupCode()的函数。所有代码如下所示。

当我在 Windows 上运行应用程序时,我得到预期的行为 - 正确的时间顺序弹出3条消息(例如,每个Sleep()仅在上一个对话框后启动单击确定)已确认框。

当我在 iOS Android 上运行应用时,我首先弹出最后一条消息(“睡眠2秒”),但仅在整个时间过后( 12.25秒)。然后在通过单击“确定”确认之后立即收到“睡眠10秒”消息,同样在此之后我收到“睡眠季度秒”消息。

#include <System.SysUtils.hpp>

void StartupCode()
{
    Sleep(250);
    ShowMessage("Slept quarter sec");
    Sleep(10000); 
    ShowMessage("Slept 10 sec");
    Sleep(2000); 
    ShowMessage("Slept 2 sec");
}

void __fastcall TForm1::FormShow(TObject *Sender)
{
    #if defined(_PLAT_IOS) || defined(_PLAT_ANDROID)
      TThread::ForceQueue(nullptr, [this](){StartupCode();});
    #endif

    #if defined(_PLAT_MSWINDOWS)
      StartupCode();
    #endif
}

我是绿色的,只是想学习一点。当我遇到这种奇怪的行为时,我正在测试一个线程是否会遇到Apple的应用程序启动看门狗定时器的麻烦。

为什么会出现这种情况?

1 个答案:

答案 0 :(得分:2)

ShowMessage()在10.2东京的移动平台上的行为与您期望的完全不同。

根据10.2 Tokyo documentation

  

ShowMessage在不同平台上的表现不同

     

在桌面平台上,ShowMessage同步运行。仅当用户关闭对话框时,调用才会结束。

     

在移动平台上,ShowMessage的行为是异步的。呼叫即时结束,它不会等待用户关闭对话框

     

如果您想在不同平台上强制执行特定行为,请使用IFMXDialogServiceAsync.ShowMessageAsync单元中的IFMXDialogServiceSync.ShowMessageSyncFMX.Platform

根据10.0 Seattle documentation

  

在移动平台上,对ShowMessage的呼叫未被阻止。这意味着在调用ShowMessage之后放置的任何代码都会在对话框关闭之前执行。如果您需要在关闭对话框后执行代码,请使用MessageDlg代替ShowMessage

因此,在您的情况下发生的情况是,您对ShowMessage()的调用会立即返回StartupCode(),在后台排队对话框。然后处理对Sleep()的所有调用,然后执行返回到主UI循环,然后主循环显示所有3个对话框,一个在另一个上面,第一个在底部最后一个在顶部。这就是为什么你看到它们以相反的顺序出现的原因。

注意:Android不支持模态/同步对话框!因此,IFMXDialogServiceSync.ShowMessageSync()未在Android上实施,仅实施了IFMXDialogServiceAsync.ShowMessageAsync()

在柏林10.1之前,ShowMessage()内部调用了IFMXDialogService.MessageDialog()同步版本(与上面的西雅图文档所说的相反),该版本适用于iOS,但提出了ENotImplemented Android上的{1}}例外。

ShowMessage()(和MessageDlg())为deprecated in 10.1 Berlin

我没有安装10.1柏林或10.2东京来检查这些系统内部ShowMessage()的内容,但听起来它更新为在iOS和Android上使用IFMXDialogServiceAsync.ShowMessageAsync(),如果你没有在Android上获得ENotImplemented例外。

注意:您看到的行为与TThread::ForceQueue()broken on Android in 10.2 Tokyo,BTW)无关。此外,TThread::ForceQueue()不会像您声称的那样启动新主题。