【发布时间】:2014-09-04 09:14:43
【问题描述】:
在 Android 上,当我在点击后 15 秒的长时间功能(所需时间 > 30 秒)期间触摸屏幕时,会出现“应用程序没有响应”的消息。 我不想看到它。
我做了一个测试项目,有 2 个按钮和一个函数“LongProcess”,用于模拟一个长过程(它只是 30 秒的睡眠)。我的第一个按钮“LaunchFunction”只是调用该函数。我的第二个按钮“LaunchThread”,启动一个将执行我的“LongProcess”的线程。 在第一种情况下,我遇到了问题,但在第二种情况下,它运行良好(消息永远不会出现,因为我的主窗体没有等待)。
但是,我必须等待“LongProcess”的结束(因此线程的结束),因为我必须在它之后做其他需要“LongProcess”结果的事情。所以我试图用很多方法等待我的线程。我尝试使用 TThread 类的“WaitFor”,但它重复了最初的问题。我也尝试了一个简单的“while”。
while not fThread.Finished do
begin
Sleep(500);
end;
但它是相同的,如果我触摸屏幕,弹出将再次出现。 关键部分而不是“while”或“Thread.WaitFor”做了完全相同的事情。
所以我尝试在“while”中更新 GUI,以向 Android 显示应用程序正在运行。
while not fThread.Finished do
begin
Sleep(100);
Label_Test.Text := 'Msg' + IntToStr(i);
Inc(i);
Application.ProcessMessages;
end;
我看到我的标签值发生了变化,如果我触摸屏幕没有任何变化。 15 秒后我会有弹出窗口(但我仍然会看到我的标签在后台更新)。
有人有想法吗?也许我们可以在一个漫长的过程中禁用事件(所以点击不会在队列中,所以他不应该被认为在 15 秒后“没有响应”)。 Application.ProcessMessage 在 Android 上似乎不起作用。 或者可能存在 Android API 中的某些内容来说明我们不是处于非活动状态的操作系统?
最后,如果我点击“等待”,应用程序将完美运行。如果我也不触摸屏幕(也没有线程,直到我不触摸屏幕),但我看到很多用户像机器人一样点击“确定”(这会关闭应用程序...) . Ty 为您提供未来的帮助
ps : 我尝试用计时器替换线程,因为我在论坛上看到它,但它什么也没改变。
ps2:这里是 .zip 或演示项目 http://www.partage-facile.com/YOJT1A8CLE/testproject.rar.html
【问题讨论】:
-
如果将 Sleep(nnn) 放入主线程,将 LongProcess() 放入单独的线程是没有意义的。
-
如果你阻塞主线程太久,你会得到一个 ANR。没有办法解决它。不要试图让你的应用等待。只需在单独线程中的 LongProcess 末尾启动您的“其他事情”。
-
软件流必须是事件驱动的。永远不要在主线程中等待长线程任务完成。而是为线程声明
OnTerminate事件,通知主线程工作完成。
标签: android delphi mobile delphi-xe6 android-anr-dialog