B4A Class [B4X] CallSubPlus - CallSub with explicit delay

pesquera

Active Member
Licensed User
- Make sure to include an underscore in the target subs names if you intend to compile with obfuscation.
What could happen if not? I must to use CallSubDelayedPlus and wanted to know more about that

I noticed on ClientKVS Class that you does not include an underscore on the Sub HandleQueue, and seems to be fine compiling with obfuscation
B4X:
csu.CallSubDelayedPlus(Me, "HandleQueue", 30000)
 

Erel

Administrator
Staff member
Licensed User
Check the last line in ClientKVS.Initialize:
B4X:
If False Then CallSub(Me, "HandleQueue") 'to avoid obfuscation issues
This line causes the compiler to avoid obfuscating HandleQueue name.
 

Dave O

Active Member
Licensed User
This is very handy when dealing with animations.

For example, when the user opens the nav drawer and taps an item, the nav drawer typically takes ~100ms to close. When I tried updating the UI on the activity, it caused the drawer animation to stutter (because they were happening at the same time).

Using CallSubDelayedPlus, however, I give it a 150ms delay and everything is smoothy goodness. :)

Thanks Erel!
 

Erel

Administrator
Staff member
Licensed User
You can add a global flag and check it in the target sub.
 

Stern0m1

Member
Licensed User
Thats what I have been doing. I think a more efficient way would just be a command to cancel. There should be a way to timer.enabled = false in the class. I just dont know anything about classes.

Thanks
 

ilan

Expert
Licensed User
hi,

i have a question please.

i see now that in the CallSubUtils Class in tmr_Tick
when rdd.Delayed is false then the sub will be called with CallSub and not CallSubDelayed. that make sense because this is what we want. (use CallSub and not CallSubDelayed, only in speciffic cases like calling a sub inside the same module)

but my question is, if you call a sub with CallSub and the Module is Paused then you may get a crash right?

should there not be an if statement before trying to call that sub??

this is the original code:

B4X:
Private Sub tmr_Tick
    Dim t As Timer = Sender
    t.Enabled = False
    Dim rdd As RunDelayedData = RunDelayed.Get(t)
    RunDelayed.Remove(t)
    If rdd.Delayed Then
        If rdd.Arg = Null Then
            CallSubDelayed(rdd.Module, rdd.SubName)
        Else
            CallSubDelayed2(rdd.Module, rdd.SubName, rdd.Arg)
        End If
    Else
        If rdd.Arg = Null Then
            CallSub(rdd.Module, rdd.SubName)
        Else
            CallSub2(rdd.Module, rdd.SubName, rdd.Arg)
        End If
    End If
End Sub
this is how i think it should look like (but i may be wrong)

B4X:
Private Sub tmr_Tick
    Dim t As Timer = Sender
    t.Enabled = False
    Dim rdd As RunDelayedData = RunDelayed.Get(t)
    RunDelayed.Remove(t)
    If rdd.Delayed Then
        If rdd.Arg = Null Then
            CallSubDelayed(rdd.Module, rdd.SubName)
        Else
            CallSubDelayed2(rdd.Module, rdd.SubName, rdd.Arg)
        End If
    Else
        If IsPaused(rdd.Module) Then Return 'CHECK FIRST IF MODULE IS NOT PAUSED
        If rdd.Arg = Null Then
            CallSub(rdd.Module, rdd.SubName)
        Else
            CallSub2(rdd.Module, rdd.SubName, rdd.Arg)
        End If
    End If
End Sub
 

ilan

Expert
Licensed User
CallSub will never crash because of a paused activity.
i could reproduce it in this simple example.

the crash is related to the timers in CallSubUtils

when you intialize callsubuitls in the starter service and then call it from 1 activity but before the timer tick was called you switch to another activity you may get this error:

LogCat connected to: 4b2f02ef
--------- beginning of main~i:** Service (firebasemessaging) Start **
Message arrived
Message data: {body=נא לבדוק שאתם בחשבון הראשי עבודה מס 1, title=נעלמו לכם המשמרות? יש פתרון}
--------- beginning of system
Copying updated assets files (2)
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Billing service disconnected.
Billing service disconnected.
Billing service connected.
Checking for in-app billing 3 support.
In-app billing version 3 supported for www.sagitalcashlite.net
Subscriptions AVAILABLE.
Billing service connected.
Checking for in-app billing 3 support.
In-app billing version 3 supported for www.sagitalcashlite.net
Subscriptions AVAILABLE.
Ignoring event: manager_billingsupported
Ignoring event: manager_billingsupported
** Activity (main) Pause, UserClosed = false **
** Activity (act2) Create, isFirst = true **
** Activity (act2) Resume **
** Activity (act2) Pause, UserClosed = true **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (act2) Create, isFirst = false **
** Activity (act2) Resume **
** Activity (act2) Pause, UserClosed = false **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (act2) Create, isFirst = false **
** Activity (act2) Resume **
** Activity (act2) Pause, UserClosed = false **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (act2) Create, isFirst = false **
** Activity (act2) Resume **
** Activity (act2) Pause, UserClosed = false **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
java.lang.RuntimeException: java.io.EOFException
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:165)
at anywheresoftware.b4a.objects.Timer$TickTack.run(Timer.java:105)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: java.io.EOFException
at java.io.DataInputStream.readByte(DataInputStream.java:77)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:335)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:249)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
... 8 more
what i did to solve it i check if the activity is paused, if true then it wont be called with callsub.
i also stop all timers and delete them when i exit my app. this function is important.

B4X:
Public Sub StopAll
        If RunDelayed.IsInitialized Then
            For Each tmr As Timer In RunDelayed.Keys
                tmr.Enabled = False
            Next
            RunDelayed.Clear
        End If       
End Sub
let say i want to show an ad in 2 seconds so i call csu.... now if the user exit the app then it is not relevant anymore to show that ad so i stop all timers and clear the map otherwise when he will return the timer event will be raised and i dont want that. so the StopAll function is important is some cases.
 

Attachments

Erel

Administrator
Staff member
Licensed User
I don't see any crash here (tested in debug mode). I pressed on Show msg and then switched activity.

The error message you posted looks like a debugger error. Do you see an error in release mode?
 

ilan

Expert
Licensed User
I don't see any crash here (tested in debug mode). I pressed on Show msg and then switched activity.

The error message you posted looks like a debugger error. Do you see an error in release mode?
in release mode i cant reproduce it but yesterday i am sure i got the same error in release mode.
when i returned to the app i was thrown out and i saw the same error (something with the timer in csu class)

i need to mention that i exit the app with home button. i am not sure if it is related to that.
will make more tests and let you know if i found something.

thanx, ilan
 

ilan

Expert
Licensed User
ok i got a crash on release mode on my app, this is the log:

** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (menu) Create, isFirst = false **
6
jd: 2457836.8628442595
Freitag:
18:54 | 11:42:29
zmanit:1
shabbat = false
bug fixed
XXXX USERID =
0
** Activity (menu) Resume **
adOut: false
START LOAD TIMER
ad failed to load
3
######STARTINT: 1
######HDT: 03/2017
received
######STARTINT: 1
######HDT: 04/2017
######STARTINT: 1
######HDT: 03/2017
######STARTINT: 1
######HDT: 02/2017
######STARTINT: 1
######HDT: 01/2017
######STARTINT: 1
######HDT: 02/2017
######STARTINT: 1
######HDT: 03/2017
######STARTINT: 1
######HDT: 02/2017
callsubutils_tmr_tick (java line: 181)
java.lang.NullPointerException: Attempt to read from field 'boolean www.sagitalcashlite.net.callsubutils$_rundelayeddata.Delayed' on a null object reference
at www.sagitalcashlite.net.callsubutils._tmr_tick(callsubutils.java:181)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:179)
at anywheresoftware.b4a.objects.Timer$TickTack.run(Timer.java:105)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
EDIT: it could be because the csu was intialized in activity main, i moved it to starter service let see if i get that crash again.

btw is there a reason why the CallSubUtils "Library" (not class) does not compile on debug mode?
 
Last edited:

Erel

Administrator
Staff member
Licensed User
It works fine here in debug mode. Please start a new thread in the questions forum and explain what is not working.
 
Top