2014-09-04 118 views
2

在Android上,当我在点击15秒后的长时间功能(所需时间> 30秒)期间触摸屏幕时,会显示消息“应用程序未响应”。 我不想看到它。应用程序没有响应 - Delphi XE6 - Android

http://4.bp.blogspot.com/-Z8NE7uPqCtQ/Uu3-3t0v_3I/AAAAAAAAAUA/A7fLKOM6iS4/s1600/Android_ANR.png

我做了一个试验项目,2个按钮和功能“LongProcess”为模拟一个漫长的过程(它只是一个30秒的睡眠)。我的第一个按钮“LaunchFunction”只是调用函数。我的第二个按钮“LaunchThread”,启动一个将执行我的“LongProcess”的线程。 在第一种情况下,我有我的问题,但在第二种情况下,它完美地工作(该消息将永远不会出现,因为我的主表单不在等待)。

但是,我必须等待“LongProcess”的结束(因此Thread的结束),因为我必须在需要“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:我试图用定时器替换线程,因为我在论坛上看到它,但它改变了nothings。

PS2:这里的.zip或示范项目http://www.partage-facile.com/YOJT1A8CLE/testproject.rar.html

+0

如果您将Sleep(nnn)放入主线程,将LongProcess()放入一个单独的线程是没有意义的。 – mg30rg 2014-09-04 09:28:51

+2

如果你阻塞主线太久,你会得到一个ANR。没有办法绕过它。不要试图让你的应用程序等待。只需在单独线程的LongProcess结尾处启动“其他事物”即可。 – 2014-09-04 09:30:49

+2

软件流程必须由事件驱动。永远不要在主线程中等待长线程任务完成。相反,为该线程声明一个'OnTerminate'事件来通知主线程该工作已完成。 – 2014-09-04 09:34:05

回答

1

如果封锁太久主线程,你会得到一个ANR。没有办法绕过它。不要试图让你的应用程序等待。只需在单独线程的LongProcess结尾处启动“其他事物”即可。

你可以尝试的是使用Timer来操作它,但这只是一个非常愚蠢的事情,Android总体上很慢,但这是你的错误。你尝试的方式真的没有办法。您可以尝试声明线程的OnTerminate事件,以通知主线程工作已完成或在没有Sleep的情况下找到不同的方式()

+0

是的,但如果我把我的“LongProcess”和以下处理线程,我怎么能禁用用户的点击,直到线程的结束? 我应该禁用所有可点击的项目吗?没有简单或灵活的解决方案? – Bramovic44 2014-09-05 07:16:46

+0

在线程启动前禁用按钮,并在线程的onterminate方法中重新启用该按钮。 – nolaspeaker 2016-03-06 12:01:09