The recent Delphi 10.2.2 Tokyo release has resulted in a flurry of reports for apps on Android that “hang” when using tab transitions, or when using “wait” animations. This article offers an explanation for the issue, as well as a potential workaround.

Update: As per E. Spelt’s suggestion on the report, I’ve modified the TThreadedTimer class to call Synchronize, rather than Queue.

TL;DR answer: You can find the workaround at the Kastri Free project.

There were a number of changes in Delphi 10.2.2. Tokyo for Android, including an endeavour to resolve UI performance issue, and part of the changes included how timers are implemented on Android. Because of the change, when any “tight” loops are introduced such as with tab transitions or “wait” animations (e.g. when using TAnimator.AnimateFloatWait), the timer events are never fired because the Android timer code runs on the same thread.

In my investigations into the issue, I discovered that it appears there may be no way to “force” the timer(s) to check if the interval has expired and therefore fire the event, so I’ve created a workaround that “shoe-horns” a thread-based timer into the animations code. Being thread-based, when Application.ProcessMessages is called, CheckSynchronize is ultimately called, and the event that the thread-based timer has queued, is called.

As per the TL;DR answer above, I have posted the workaround in the Kastri Free project. As per the warning in the readme, any workarounds posted should be treated with caution. So far, this one is working for me.

Wishing everyone a Merry Christmas, Happy Hanukkah, Malkh, Yule, Newtonmas, Festivus 😉 or whatever you celebrate at this time of year 🙂