1. *** New version of B4J is available ***
    B4J v7.8
    Dismiss Notice

Android Tutorial Static Code Modules

Discussion in 'Tutorials & Examples' started by Erel, Jan 27, 2011.

  1. Erel

    Erel Administrator Staff Member Licensed User

    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:
    Code:
    Sub ButtonsCreator(Text As StringAs Button
      
    Dim b As Button
      b.Initialize(
    "Button")
      b.Text = Text
      
    Return b
    End Sub
    From the activity module you can call:
    Code:
    Activity.AddView(CodeModule.ButtonsCreator("press here"), 10dip10dip200dip200dip)
    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).
     
    ali.hassanabadi and koaunglay like this.
  2. nfordbscndrd

    nfordbscndrd Well-Known Member Licensed User

    I'm trying to create sample code for static modules, but it's not working as expected:

    Code:
    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?
     
  3. Erel

    Erel Administrator Staff Member Licensed 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.
    Code:
    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.
     
  4. JesseW

    JesseW Active Member Licensed 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
    Code:
    Sub Process_Globals
    End Sub

    Sub Globals
       
    Dim sv As ScrollView
       
    Dim lblRecap(157As 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
    Code:
    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
     
  5. Erel

    Erel Administrator Staff Member Licensed 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.
     
  6. Kevin

    Kevin Well-Known Member Licensed 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: Aug 14, 2011
  7. JesseW

    JesseW Active Member Licensed User

    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:)
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    You cannot reference a module from a different project. You will need to make a copy of the module.
     
  9. jaminben

    jaminben Member Licensed 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
     
  10. Kevin

    Kevin Well-Known Member Licensed 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
     
  11. jaminben

    jaminben Member Licensed User

    Thanks Kevin... makes perfect sense :)
     
  12. silver

    silver New Member

    How do I call a function in another module?

    All I get is error Undeclared variable 'functionname'?
     
    Last edited: Aug 12, 2012
  13. margret

    margret Well-Known Member Licensed User

    You call it with modulename.functionname.
     
  14. Stulish

    Stulish Active Member Licensed 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
     
  15. margret

    margret Well-Known Member Licensed User

    Put your information just above the sub in the module, like:

    Code:
    'Pass a String with a complete path and file name
    'Used for .....
    Sub math()

    End Sub
    Be sure to save your project, you may even have to re-open it before the Tip shows.
     
  16. Chmava

    Chmava Member Licensed 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.
     
  17. Erel

    Erel Administrator Staff Member Licensed User

    Please start a new thread for this question (it is not specifically related to code modules).
    Yes.
     
  18. Chmava

    Chmava Member Licensed User

    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.
     
  19. Erel

    Erel Administrator Staff Member Licensed User

  20. Chmava

    Chmava Member Licensed User

    Thank you! if only i can find my first post, cant seem to access it or find it in account.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice