Italian Timer in modulo di servizio

Roberto Tsolakis

Member
Licensed User
Longtime User
Vorrei mettere in un MODULO DI SERVIZIO ... se proprio non si può in un MODULO DI CLASSE
un programma che attivato dopo un secondo (o tempo variabile impostato come parametro) di pausa lasciasse proseguire il codice.

Io ho pensato ad una cosa del genere ... ma poi come la richiamo nell'activity? In VB c'era il comando PAUSE ...

B4X:
#Region  Service Attributes
    #StartAtBoot: False
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim Secondo As Timer
End Sub
Sub Service_Create
    Secondo.Initialize("eSecondo", 1000)
End Sub

Sub Service_Start (StartingIntent As Intent)
    Secondo.Enabled = True
End Sub

Sub Service_Destroy
    Secondo.Enabled = False
End Sub


Sub eSecondo_Tick
Log("E' passato un secondo")
  Secondo.Enabled = False
End Sub


richiamando il MODULO DI SERVIZIO con


B4X:
    CallSub(NomeServizio,"Create")


Il programma in se per se funziona ... ma non sembra essere lineare. Sembra che il cell esegua prima tutto e poi dopo un secondo visualizzi il tutto.
Ed inoltre nel LOG mi da un fastidioso : Sub 'Create' not found (warnign #25)
 
Last edited:
D

Deleted member 103

Guest
Ciao Roberto,

Vorrei mettere in un MODULO DI SERVIZIO ... se proprio non si può in un MODULO DI CLASSE
E chi dice che non si può metter un Timer in um Modulo di Classe?

Comunque, per richiamare il servizio usa questo:
B4X:
StartService(NomeServizio)
 

LucaMs

Expert
Licensed User
Longtime User
Se ho capito bene vorresti qualcosa da mettere in un'Activity che ti consenta di fare una pausa.

In pratica DOVRESTI creare una classe, all'interno della quale un timer e, scaduto il tempo, richiamare tramite CallSubDelayed una routine dell'Activity chiamante.
Il tutto è però superfluo, perché è la stessa identica cosa che aggiungere un timer direttamente nell'Activity.

Cioè, dovresti fare:

Activity

Dim objMiaClassePausa As MiaClassePausa
objMiaClassePausa.Initialize(Me, 1000) ' ms

sub PausaTerminata
' qui riprenderebbe
End sub

MiaClassePausa
Private mChiamante As Object
Private tmrScadenza As Timer
Sub Initialize(Chiamante As Object, Durata As Int)
mChiamante = Chiamante
tmrScadenza.Initialize("tmrScadenza", Durata)
' qui decidi se far partire subito il timer
tmrScadenza.Enabled = True


trmScadenza_Tick
If SubExists(mChiamante, "PausaTerminata") Then
CallSubDelayed(mChiamante, "PausaTerminata")
End If
End Sub

Tutta sta pappa per dire che sarebbe uguale ad un timer direttamente nell'Activity (magari, però, si vede come creare una classe - da trasformare poi in libreria - e lanciare una routine del chiamante, il che significa creare un evento).
 

LucaMs

Expert
Licensed User
Longtime User
Benché Erel dica (quasi giustamente, secondo me) che non si dovrebbe "bloccare" il thread principale (Main), eventualmente puoi mettere in un modulo di codice di utilità (oppure farne una libreria) questo SUO codice!:

B4X:
Sub WaitFor(Milliseconds As Int)
    Dim s As Long
    s = DateTime.Now
    Do While DateTime.Now < s + Milliseconds
    Loop
End Sub
 

Roberto Tsolakis

Member
Licensed User
Longtime User
Filippo .... Grazie, non credevo si potesse richiamare un modulo di servizio più volte con startservice!

Luca ...
Dirò un eresia ... questa pausa mi serve semplicemente per cambiare lo sfondo di un Button indicizzato ... e visto che non sto usando il desiner, mi risulterebbe un pò lungo in tutte le activity ricreare il timer (o cosa più brutta richiamarlo da un'altra activity).

Ad ogni modo ... un like a tutti e due!
 

LucaMs

Expert
Licensed User
Longtime User
Perché ti serve una pausa per cambiare lo sfondo? Per motivi legati proprio al progetto?

Altrimenti dovresti usare StateListDrawable (se vuoi che cambi quando viene premuto):

B4X:
Public Sub ButtonSetStateListDrawable(btnBitmap As Button, EnabledBitmap As Bitmap, PressedBitmap As Bitmap, DisabledBitmap As Bitmap)
    ' Define a bitmap for Enabled state
    Dim bdwEnabled As BitmapDrawable
    bdwEnabled.Initialize(EnabledBitmap)
   
    ' Define a bitmap for Pressed state
    Dim bdwPressed As BitmapDrawable
    bdwPressed.Initialize(PressedBitmap)

    ' Define a bitmap for Disabled state
    Dim bdwDisabled As BitmapDrawable
    bdwDisabled.Initialize(DisabledBitmap)

    ' Define a StateListDrawable
    Dim stdBitmap As StateListDrawable
    stdBitmap.Initialize
    Dim states(2) As Int
    states(0) = stdBitmap.state_enabled
    states(1) = -stdBitmap.state_pressed
    stdBitmap.addState2(states, bdwEnabled)
    Dim states(1) As Int
    states(0) = stdBitmap.state_enabled
    stdBitmap.addState2(states, bdwPressed)
    Dim states(1) As Int
    states(0) = stdBitmap.State_Disabled
    stdBitmap.addState2(states, bdwDisabled)
   
    ' Set stdBitmap to button btnBitmap
    btnBitmap.Background = stdBitmap
End Sub
 

Roberto Tsolakis

Member
Licensed User
Longtime User
Beh in fin dei conti ...
Ho imparato tre cose nuove!

Io non capisco come fate voi ... i tutorial in inglese sono un pò confusi ... gli esempi un pò troppo lunghi da seguire ...
Il libro di Luigi ce l'ho in una versione impaginata male ... ma credo sia l'ultima (2.5) e comunque non esaustivo.
Per carità ha fatto un buon lavoro ... e tre anni fa mi ci son messo a leggerlo tutto e gli ho segnalato vari errori (più che altro di impaginazione), ma nel frattempo B4A si è evoluto (e credo che questo lo sappia anche lui).
 

MarcoRome

Expert
Licensed User
Longtime User
Benché Erel dica (quasi giustamente, secondo me) che non si dovrebbe "bloccare" il thread principale (Main), eventualmente puoi mettere in un modulo di codice di utilità (oppure farne una libreria) questo SUO codice!:

B4X:
Sub WaitFor(Milliseconds As Int)
    Dim s As Long
    s = DateTime.Now
    Do While DateTime.Now < s + Milliseconds
    Loop
End Sub
Ciao Luca toglierei il "quasi giustamente" :) Se blocchi il thread spesso rischi di fare andare in crash l'app.
 

LucaMs

Expert
Licensed User
Longtime User
Ciao Luca toglierei il "quasi giustamente" :) Se blocchi il thread spesso rischi di fare andare in crash l'app.

L'ho messo per un motivo preciso. Secondo Erel non si dovrebbe usare il DoEvents (nell'eventuale loop). Io non concordo: è proprio per evitare di bloccare il thread che il DoEvents è utile e necessario.
 

LucaMs

Expert
Licensed User
Longtime User
Dovremmo fare una prova: un loop "infinito" con un DoEvents all'interno. Io sono (quasi) certo che l'app non andrà in crash.
 

LucaMs

Expert
Licensed User
Longtime User
L'idea di provare non è male ;) ... fammi sapere
Devo prima imparare quella nuova cosetta sull'intercettazione di un'eccezione (non ricordo nemmeno in quale versione di b4a sia stata implementata per la prima volta).

Poi farotti sapere di sicuro :)
 

MarcoRome

Expert
Licensed User
Longtime User
In ogni caso se hai funzioni "sincrone" che durano oltre i 5 secondi ( bloccano il thread ) Android chiuderà le stesse.
( Esperienza personale su una libraria sviluppata tempo fa, vedi QUI )
Vedi anche Articolo
 

LucaMs

Expert
Licensed User
Longtime User
Sì, anche Erel disse 5"... poi pubblicai un'app di test in cui questo non accadeva.

Comunque, ti allego il progettino di prova che mi da errore in fase di compilazione, pur avendo in pratica solo 3 linee di codice.
Non chiedo sul forum "inglese" perché ieri Erel mi ha fatto girare i maroni :D. Se vuoi farlo tu...!
 

Attachments

  • DoEventsTest.zip
    7.8 KB · Views: 128

LucaMs

Expert
Licensed User
Longtime User
E' un bug di B4A (5.50).

Così non compila:
B4X:
Do While True
    DoEvents
Loop


così sì:
B4X:
Dim T As Boolean = True
Do While T
    DoEvents
Loop
 

MarcoRome

Expert
Licensed User
Longtime User
Sì, anche Erel disse 5"... poi pubblicai un'app di test in cui questo non accadeva.

Comunque, ti allego il progettino di prova che mi da errore in fase di compilazione, pur avendo in pratica solo 3 linee di codice.
Non chiedo sul forum "inglese" perché ieri Erel mi ha fatto girare i maroni :D. Se vuoi farlo tu...!
:D sei tremendo e....
 

LucaMs

Expert
Licensed User
Longtime User
un po' cocciuto, diciamo: se hanno messo il comando DoEvents, un motivo ci sarà (comando che tra l'altro ho usato spesso con VB.Net!).
 

LucaMs

Expert
Licensed User
Longtime User
L'app col loop sta girando da almeno 5 min, senza crash.

P.S. messa in pausa, aperto Chrome, riattivata... nessun crash
 

LucaMs

Expert
Licensed User
Longtime User
Ecco, dà problemi, qualche volta, quando la "riesumi"... ma probabilmente questo è dovuto al fatto che il loop è inserito proprio nella Resume; se fosse in un evento Button_Click forse non ne darebbe (e uno potrebbe dire: "e provace" :D)
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Ecco, da problemi, qualche volta, quando la "riesumi"... ma probabilmente questo è dovuto al fatto che il loop è inserito proprio nella Resume; se fosse in un evento Button_Click forse non ne darebbe (e uno potrebbe dire: "e provace" :D)

...e c'ho provato... infatti, avviando il loop in un posto diverso dalla Resume, nessun crash, nessun problema.
 
Top