Android Question [Solved] [B4xPages] Sub does not exist when compiled in release obfuscated

marcick

Well-Known Member
Licensed User
Longtime User
Hi all,
I’m writing a class that performs callbacks to the calling page, but the callbacks don’t work.
To understand where the problem is, I did several tests. I discovered that the callback sub is considered as not existing, even when I check it directly inside the page where it is defined.
For example, inside the page that contains the sub, this returns False:

B4X:
Private Sub B4XPage_Appear
    Log("EXISTS: " & SubExists(Me, "Test"))
End Sub

Private Sub Test
    log("Test")
End Sub

logged: EXISTS: false

This happens only when compiling in Release Obfuscated.
In Debug and Release (not obfuscated) it works correctly.

I’m using B4A 13.40.

Am I doing something wrong?
 

marcick

Well-Known Member
Licensed User
Longtime User
Thanks guys, I was going crazy over this 😅
I didn’t realize that, with obfuscation enabled, subs without an underscore can be renamed and therefore can’t be found via SubExists / CallSub*.
Adding an underscore to the callback sub name fixed the issue completely.


Really appreciate the clarification!
 
Upvote 0

Derek Johnson

Active Member
Licensed User
Longtime User
Just to chip in on an old thread but I think the answers are confusing and possibly wrong. I was having similar issues with implementing obfuscation.
The OP said
I’m writing a class that performs callbacks to the calling page, but the callbacks don’t work.

Private Sub B4XPage_Appear
Log("EXISTS: " & SubExists(Me, "Test"))
End Sub

Private Sub Test
log("Test")
End Sub

logged: EXISTS: false

If this code appeared in the class module 'Me' would refer to the subs in the class module and therefore I would expect the Test sub to be found, and it is.

If the Test sub is in the calling module, it will not be found because 'Me' is the wrong context, it should be the module name eg "Main" or some such.
This is regardless on obfuscation.

The code below shows the various possible scenarios:

Test Example:
Sub Class_Globals
    
End Sub

'Code in Main:
'Private Mytest As Qtest 'in Globals
'    Mytest.Initialize(Me)
'This is the callback sub in Main

'Sub MainTest(msg As String)
'    Log("Hello from MainTest: " & msg)
'End Sub

'Code in Class Module
'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize (Target As Object)
    'Quick check
    LogColor("EXISTS: " & SubExists(Me, "Test"), Colors.Blue)
    CallSub2(Me,"Test","No delay")
    CallSubDelayed2(Me,"Test","Delayed")
    Log("After Local Test")
    
    LogColor("Target EXISTS: " & SubExists(Target, "MainTest"), Colors.red)
    CallSub2(Target,"MainTest","No Delay")
    CallSubDelayed2(Target,"MainTest","Dalayed")
    Log("After target Test")
    
    LogColor("MAIN EXISTS: " & SubExists(Main, "MainTest"), Colors.magenta)
    CallSub2(Main,"MainTest","No Delay")
    CallSubDelayed2(Main,"MainTest","Delayed")
    Log("After Main Test")
    
End Sub

Private Sub Test(msg As String)
    Log("Local: Tested OK: " & msg)
End Sub

If I compile and run this in obfuscated mode this I get this in the log:

EXISTS: true
Local: Tested OK: No delay
After Local Test
Target EXISTS: true
Hello from MainTest: No Delay
After target Test
MAIN EXISTS: true
Hello from MainTest: No Delay
After Main Test
Local: Tested OK: Delayed
Hello from MainTest: Dalayed
Hello from MainTest: Delayed

This show that the tests for the existence of subs does work in obfuscated mode and that you can use callbacks to the calling module.

HTH
 
Upvote 0

marcick

Well-Known Member
Licensed User
Longtime User
Thanks for your input. Just to clarify one important point: the code in my original example was not inside the class module.

As I wrote in the first post, I deliberately tested SubExists(Me, "Test") directly inside the same B4XPage where Test was defined, in order to isolate the problem from the callback/Target mechanism.

With B4A 13.40, the exact code I posted returned False when compiled in Release Obfuscated, while it returned True in Debug and normal Release.

Adding an underscore to the sub name fixed it immediately.

So the issue I reported was not related to using Me instead of the callback target. Your test does seem to behave differently in obfuscated mode, though, which is interesting. Perhaps something has changed in the obfuscation behavior in newer B4A versions.
 
Upvote 0

Alessandro71

Well-Known Member
Licensed User
Longtime User
Thanks for your input. Just to clarify one important point: the code in my original example was not inside the class module.

As I wrote in the first post, I deliberately tested SubExists(Me, "Test") directly inside the same B4XPage where Test was defined, in order to isolate the problem from the callback/Target mechanism.

With B4A 13.40, the exact code I posted returned False when compiled in Release Obfuscated, while it returned True in Debug and normal Release.

Adding an underscore to the sub name fixed it immediately.

So the issue I reported was not related to using Me instead of the callback target. Your test does seem to behave differently in obfuscated mode, though, which is interesting. Perhaps something has changed in the obfuscation behavior in newer B4A versions.
underscore prevents subs name obfuscation.
 
Upvote 0

Derek Johnson

Active Member
Licensed User
Longtime User
Thanks for your input. Just to clarify one important point: the code in my original example was not inside the class module.

As I wrote in the first post, I deliberately tested SubExists(Me, "Test") directly inside the same B4XPage where Test was defined, in order to isolate the problem from the callback/Target mechanism.

With B4A 13.40, the exact code I posted returned False when compiled in Release Obfuscated, while it returned True in Debug and normal Release.

Adding an underscore to the sub name fixed it immediately.

So the issue I reported was not related to using Me instead of the callback target. Your test does seem to behave differently in obfuscated mode, though, which is interesting. Perhaps something has changed in the obfuscation behavior in newer B4A versions.
I'm running the code compiled with B4A 13.70 and SDK target version 36. The app I tested this in was not a Pages App.

I was quite pleased when I found that I could use the function calls from my class module without renaming them and that they still worked. This saved me a lot of renaming and testing effort and also made the obfuscation more effective. I haven't bothered to use obfuscation up till now but Google are now saying that if you don't obfuscate your code you may not get your App listed in Playstore. Why they should do this is a mystery to me though.
 
Upvote 0
Top