2014-09-04 115 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