2017년 1월 2일 월요일

cannot change label text programmatically within while loops


I coded an app that sends a bunch of text SMS to the same person (me). I implemented a sort of "wait" block to avoid the errors I initially got (perhaps) because the app was sending the sms too fast one after the other.

I want to show on a label Text the status of the send process, such as "sending SMS 1 of 5..." and so on, but my app behaves completely differently: when I tap over "YES" in the confirmation dialog, the app "freezes" with the YES button still down and colored, until I get the final Message dialog telling me that all the sms have been sent. The confirmation dialog lets me see a part of the underlying label, and I can see that it does not change at all.

Why?

How could I force the confirmation dialog box to close before starting sending sms? How could I show the various messages using the label during the process?

Finally (I don't know if it's possible with AI2), could I catch exceptions to track exactly how many sms have been really sent successfully?

Please see the attached blocks for any detail.


--
Why?

use a clock component, timer interval = 1000, timer enabled = false and a global variable as counter 

in the button.click event enable the clock
inside the clock.timer event increment the counter variable and send the current message
if counter = numberOfSmsToSend then disable the clock

--
I read the post about single-thread some days ago, and I understood why I couldn't approach the problem using timers. The 1st version of my app implemented the so-deprecated wait feature using a timer resetting a boolean flag used as a condition to exit from an infinite while loop. The app did not function at all, resulting in a real infinite loop doing nothing. That was so because, as we could read in the link you gave me, AI2 enabled the timer, but did not ackowledge its "fired" event until it would have arrived at the end of the procedure, that is never. It queues the request from the timer having fired, but would pass the control to it only after its own end.

So I moved to a different approach, as you can see looking at my blocks: I use a timer not to react to its firing event, but to check the time elapsed from an initial moment onwards. It works fine.

I tried following your advice, using a 2nd clock fire event to (re)print (every 500ms) the status label text with the contents of a global string variable set within the for loop. As I was expecting, though, it did not work: the timer fired every 500ms but, being Ai2 in single-thread mode, its fired event code did not execute until the end of the procedure containing the for loop, when it's too late. Even following your advice literally would not work, beside having a counter incremented with no relationship with the sms actually sent.

All problems remain: the confirmation dialog does not close, its "YES" button remain freezed down and the label text does not update. Why so? In Delphi :) I used to code a component.Update/Invalidate/Refresh/Update followed by a Application.ProcessMessages if changing the aspect of interface components within long loops. Could it be something similar here in Android?
--
it seems to be, you did not understand what I was saying
therefore I prepared a small doSomething example for you, see screenshot and attachment
 2DoSomething.JPG




--
As a matter of fact, I really did not understand your advice. Now I followed your approach and all went right. Thank you again.

The only thing is that I'm trying to sent very long sms (corresponding to a bit less than 10 normal ones, that is a bit less of 160+145+8*152 characters). I imagined these sendings would require some time to complete, so I coded a pause of 5 sec between each one. On a Samsung S5 (with operator A) it all goes fine, while on a Samsung S4mini and Samsung Note 3 (both with operator B) I receive a "Generic failure, message not sent" for the 2nd sms, while they send succesfully the 3rd one (I did not try sending more than 3 "long" sms). I am about to increase the duration of the pause, as I imagine it could be something related to connection speed.

By the way, as far as you know, is there a way to catch these exceptions and react consequently in AI2, for istance retrying to send the sms generating failures? If not, could it be possible converting the ai2 code into plain java and then adding some exceptions handling structure?

--
you can try to catch the error in the Screen.ErrorOccurred block

--

댓글 없음:

댓글 쓰기