我有一个简单的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的应用程序启动看门狗定时器的麻烦。
为什么会出现这种情况?
答案 0 :(得分:2)
ShowMessage()
在10.2东京的移动平台上的行为与您期望的完全不同。ShowMessage在不同平台上的表现不同
在桌面平台上,
ShowMessage
同步运行。仅当用户关闭对话框时,调用才会结束。在移动平台上,
ShowMessage
的行为是异步的。呼叫即时结束,它不会等待用户关闭对话框。如果您想在不同平台上强制执行特定行为,请使用
IFMXDialogServiceAsync.ShowMessageAsync
单元中的IFMXDialogServiceSync.ShowMessageSync
或FMX.Platform
。
在移动平台上,对
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()
不会像您声称的那样启动新主题。