Android Tutorial Static Code Modules

Basic4android v1.2 includes a new type of module which is the static code module.
Adding a static code module is done by choosing Project - Add New Module - Code Module.

Unlike Activities and Services, code modules are not related in any way with Android process life cycle. These are just containers for code.
All of the subs in these modules are public and can be accessed from other modules.

Code modules use cases include:
- Avoiding duplicate code in multiple modules.
- Sharing code between projects. For example you can create a code module that parses some file. Later you can easily reuse this module in other applications.
- Separating your application logic. Each code module can be used for a specific task. This will make your program clearer and easier to maintain.

As a code module is not tied to an activity or service it uses the calling component context when required.
For example, calling a code module sub that shows a Msgbox from an activity will work. However if you call it from a service it will fail as services are not allowed to show dialogs.

Code modules cannot catch events.
While you can use a code module to initialize a button for example:
B4X:
Sub ButtonsCreator(Text As String) As Button
  Dim b As Button
  b.Initialize("Button")
  b.Text = Text
  Return b
End Sub
From the activity module you can call:
B4X:
Activity.AddView(CodeModule.ButtonsCreator("press here"), 10dip, 10dip, 200dip, 200dip)
Now in order to catch the click event you should create a sub named Button_Click.
This sub should be located in the Activity module, as Code modules cannot catch events.
CallSub which internally uses the events mechanism cannot be used to call code module subs (which can be called directly instead).
 

nfordbscndrd

Well-Known Member
Licensed User
Longtime User
I'm trying to create sample code for static modules, but it's not working as expected:

B4X:
Main:
Sub Process_Globals
   Dim i As Int
End Sub
 
Sub Activity_Create
   i = 1
   Mod1.Do1
End sub
 
Mod1:
Sub Do1
   Dim j As Int
   j = i + 1
End Sub

Your post says that subs "can be called directly" and "All of the subs in these modules are public and can be accessed from other modules."

I consider "called directly" to simply be "Do1" (as in VB6) rather than "Mod1.Do1".

In the IDE under Sub Process_Globals, it says: "These variables can be accessed from all modules", which I took to mean that the variables AND THEIR VALUES could be shared among modules. Yet when I run the code above, I get the error that in Sub Do1, "Undeclared variable 'i' is used before it was assigned any value." Am I doing something wrong, or is it just that the values can NOT be shared?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
The values can be shared but you need to prefix the variable with the module name. There could be several variables named i in different modules.
B4X:
Main:
Sub Process_Globals
   Dim i As Int
End Sub
 
Sub Activity_Create
   i = 1
   Mod1.Do1
End sub
 
Mod1:
Sub Do1
   Dim j As Int
   j = i + 1
End Sub
You cannot call a Sub in a different Activity or Service. You will need to use CallSub for that. This is what I meant with direct calling a Sub that belongs to a code module.
 

JesseW

Active Member
Licensed User
Longtime User
Market apps

I am preparing my first app for market, and I'm considering having a free version that has a 4 second splash, instead of 2 seconds, and an AdMob view at the bottom of the screen.

I didn't find any reference in the forums for the best way to achieve this, so I've created a code module and managed all the code from the activity module to the code module. Like this:

Main: Activity module
B4X:
Sub Process_Globals
End Sub

Sub Globals
   Dim sv As ScrollView
   Dim lblRecap(15, 7) As Label
   Dim lstRecap As List
   Dim tmrSplash As Timer
   Dim pnlSplash As Panel
End Sub

Sub Activity_Create(FirstTime As Boolean)
   'The last parameter of the below funcion call should be:
   '  0dip for the paid version
   ' 50dip for the free version to make room for the AdMob view
   Recap.ActivityCreate(FirstTime, Activity, lblRecap, sv, pnlSplash, tmrSplash, 0dip)  'use code module code
End Sub

Sub Activity_Resume
   Recap.ActivityResume(lstRecap, lblRecap)  'use code module code
End Sub

Sub Activity_KeyPress(KeyCode As Int) As Boolean
   If keycode = KeyCodes.KEYCODE_BACK Then
      Activity.Finish
      Return False
   End If
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

'The only click event for the 54 display labels
Sub lblRecap_Click
   Dim lbl As Label
   lbl = Sender
   Recap.LabelClick(Activity, lbl, lstRecap, lblRecap)  'use code module code
End Sub

Sub tmrSplash_tick
   pnlSplash.Visible = False
   tmrSplash.Enabled = False
End Sub

Recap: code module
B4X:
Sub Process_Globals
   ...
   'dim my global program variables here
   ...
End Sub

Sub ActivityCreate(FirstTime As Boolean, Activity As Activity, lblRecap(,) As Label, sv As ScrollView, pnlSplash As Panel, tmrSplash As Timer, AdMobOffset As Int)
   If FirstTime Then
      ...
      ' set up splash screen here
      ...
   End If
   ...
   'Set up screen display elements
   ...
End Sub

Sub ActivityResume(lstRecap As List, lblRecap(,) As Label)
   ...
   'load data from file and populate display labels
   ...
End Sub

Sub LabelClick(Activity As Activity, lbl As Label, lstRecap As List, lblRecap(,) As Label)
   ...
   'input line data from user, save in data file and update display labels
   ' the passed parameter 'lbl' is the sender label
   ...
End Sub

Sub Calc(lstRecap As List, lblRecap(,) As Label)
   ...
   'recalculate display column data based on data load or user input
   ...
End Sub

Sub Init(lstRecap As List)
   ...
   'initialize the internal data list with initial zero data
   ...
End Sub

Sub Disclaimer
   ...
   'setup disclaimer screen
   ...
End Sub

So I've placed all the 'meat' of the project code into a code module, which can be used in two projects. I plan to have one B4A project for the free version, and one for the paid version. The free version will pass '50dip' in Main.Activity_Create to Recap.ActivityCreate as the final parameter, which will move the scrollview up from the bottom 50 dip's to make room for the AdMob view and lengthen the splash screen from 2 to 4 seconds.

So I have a few questions:
1) is this the best way to achieve this 'dual apk' setup? or is there a better method, like conditional compilation that I've overlooked...
2) if yes, should I place both project file in the same folder, or have two different folders?

Thanks anyone / everyone for your help
Jesse
 

Kevin

Well-Known Member
Licensed User
Longtime User
I think I have seen it requested here before, but here is a +1 for conditional compilation (such as in VB6).

I currently use a boolean to determine demo or full version, but also plan to have two copies of the project in order to keep the "prime code" out of the demo. I may try using this code module sub to simplify things and maybe just comment out stuff that doesn't need to be in the demo (and vice versa) so I can keep it as one project and just swap commented code blocks before building. I imagine I'd also need to change the name in the project as well before compiling.

Yeah.... +1 to offer conditional compiling with the ability to conditionally add or remove code blocks and change package names based on the compiling condition chosen.

:icon_clap:
 
Last edited:

JesseW

Active Member
Licensed User
Longtime User
You can use a boolean variable to set the running mode. Though it will cause the full code to be distributed in the trial version.

I don't recommend you to place both projects in the same folder. During compilation the compiler creates all kinds of files. It assumes that there are no other projects in the same folder.

Thanks Erel.. After considering all this, I'm not even sure conditional compilation would suit this scenario, because at minimum, the free and full versions would have different package names. I think two different projects in two folders, with both accessing a single code module with any differences being in the project activity code is my best bet.

That said, is there any reason one project cannot use a code module from another project?

(well crap - I see I wasn't supposed to ask questions in this forum - my apologies for starting this discussion here :sign0148::sign0013:)
 

jaminben

Member
Licensed User
Longtime User
Hi,

Probably a dumb question but I'll ask anyway...

Code modules cannot catch events.

Does the HttpClient _responsesuccess and _ResponseError come under the cannot catch event umbrella when used in a code module? I'm guessing it does as it requires a HttpResponse ("Response") being the key word :eek:

Is there anyway around this? I've added a prefix with the module name etc but it still throws a java.lang.Exception: Sub hc_responsesuccess was not found.

Thanks
 

Kevin

Well-Known Member
Licensed User
Longtime User
Hi,

Probably a dumb question but I'll ask anyway...



Does the HttpClient _responsesuccess and _ResponseError come under the cannot catch event umbrella when used in a code module? I'm guessing it does as it requires a HttpResponse ("Response") being the key word :eek:

Is there anyway around this? I've added a prefix with the module name etc but it still throws a java.lang.Exception: Sub hc_responsesuccess was not found.

Thanks

You can use a code module to DIM and "hold" the HttpClient as well as HTTPClient-related subs, but for any activity you have in your project that uses the HTTPClient in the code module, you will need the responseSuccess and responseError subs in those activity modules as well. Any responses from the HTTP client get sent back to the calling activity.

Hopefully I explained that well enough. :D
 

jaminben

Member
Licensed User
Longtime User
You can use a code module to DIM and "hold" the HttpClient as well as HTTPClient-related subs, but for any activity you have in your project that uses the HTTPClient in the code module, you will need the responseSuccess and responseError subs in those activity modules as well. Any responses from the HTTP client get sent back to the calling activity.

Hopefully I explained that well enough. :D

Thanks Kevin... makes perfect sense :)
 

silver

New Member
How do I call a function in another module?

All I get is error Undeclared variable 'functionname'?
 
Last edited:

Stulish

Active Member
Licensed User
Longtime User
I have made a code module that works well. Is there a way of annotating it so for example:

the module is called Module.bas and it has a function called math that uses two integers

when i type in my main code:

Module.math(3,4) is there a way to add a tooltip so as i type Module.math(

the tool tip displays what the two integers are, this would make it look like functions from libraries.

I'm not sure i have explained what i want but it is basically a way to display a tooltip when using the module functions.

Thanks

Stu
 

Chmava

Member
Licensed User
Longtime User
How do i return an array or multiple variable?

on main:

arrayreturn = module.code1(x,y)
result1 = arrayreturn[0]
result2 = arrayreturn[1]

or

result1,result2 = module.code1(x,y)


on module

sub code(x as float, y as float)

return x,y

end sub

is there anywhere to accomplish this?
i need to return more then 1 variable.
 

Chmava

Member
Licensed User
Longtime User
Please start a new thread for this question (it is not specifically related to code modules).

Yes.

ok, Thank's, but why cant basic4android have a tutorial like php.net

example: PHP: mysql_query - Manual

it would make thing a whole lot easiler to search and learn, lol. the documentation is hard to navigate and impossible to understand, as no example was given.
 
Top