Android Tutorial [B4X] Tips for B4X developers

After making more than 58k posts in the forum, I decided that it is a good time to build a list of tips and common mistakes. 12 points, in no particular order:

  1. Separate code from data. Putting the data directly into the code makes your program unreadable and less maintainable.
    There are many simple ways to deal with data. For example you can add a text file to the Files tab and read it to a List with:
    B4X:
    Dim data As List = File.ReadList(File.DirAssets, "SomeFile.txt")

  2. Don't Repeat Yourself (DRY principle). If you find yourself coping and pasting the same code snippet multiple times and then making a small change then it is a good idea to stop and try to find a more elegant solution.
    Repeated code is difficult to maintain and update. The Sender keyword can help in many cases (old and still relevant tutorial: Tick-Tack-Toe: working with arrays of views).

  3. Map collection. All developers should know how to use a Map collection. This is by far the most useful collection. Tutorial: https://www.b4x.com/android/forum/threads/map-collection-the-most-useful-collection.60304/

  4. New technologies and features. Don't be afraid to learn new things. As developers we always need to learn new things. Everything is evolving whether we want it or not. I will give MQTT as a good example. I wasn't familiar with this technology. When I started learning about it I was a amazed to see how easy and powerful this solution.
    B4X specific features that all developers should be aware of:
    - Smart strings literal: https://www.b4x.com/android/forum/threads/50135/#content
    - For Each iterator: https://www.b4x.com/android/forum/threads/loops.57877/
    - Classes: https://www.b4x.com/android/forum/threads/18626/#content

  5. Logs. You should monitor the logs while your app is running. Especially if there is any error. If you are unable to see the logs for some reason then take the time to solve it. Specifically with B4A-Bridge the logs will only appear in Debug mode. If you encounter an issue that only happens in release mode then you need to switch to usb debug mode.

  6. Avoid calling DoEvents. DoEvents interferes with the internal message queue. It can cause unexpected issues. There are very few cases where it is required. This was not the case when B4A v1.0 was released. Since then the libraries have evolved and now offer better solutions. For example if the database operations are too slow (and you are correctly using transactions) then you should switch to the asynchronous methods.
    You can use the new Sleep method instead: https://www.b4x.com/android/forum/threads/79578/#content

  7. Strings are made of characters not bytes. Don't try to store raw bytes as strings. It doesn't work. Use arrays of bytes instead. The proper way to convert bytes to strings is with base 64 encoding or ByteConverter.HexFromBytes.

  8. (B4A) Use services, especially the Starter service. Services are simpler than Activities. They are not paused and are almost always accessible.
    Three general rules about global variables:
    1. All non-UI related variables should be declared in Process_Globals.
    2. Public (process_global) variables should be declared and set / initialized in Service_Create of the Starter service.
    3. Activity process globals should only be initialized if FirstTime is true.

    This is only relevant to B4A. It is simpler in B4J and B4i as there is no special life cycle and the modules are never paused.

  9. UI Layouts. B4X provides several tools to help you implement flexible layouts that adopt to all screen sizes. The main tools are: anchors and designer script. Avoid adding multiple variants (two are fine). Variants were introduced in v1.00, before the other features. Variants are difficult to maintain and can be replaced with scripts.
    Anchors are very simple and powerful.
    Don't overuse percentage units (unless you are building a game).
    http://www.b4x.com/forum/basic4andr...ing-multiple-screens-tips-best-practices.html

  10. B4J as a backend solution. B4A, B4i, B4J share the same language, same concepts and mostly the same APIs. It is also simple to exchange data between the different platforms with B4XSerializator.
    It is easy to implement powerful server solutions with B4J. Especially when the clients are implemented with B4A, B4i or B4J.

  11. Search. Use the forum search feature. You can filter results by adding the platform(b4a for example) to the query or by clicking on one of the filters in the results page.
    Most of the questions asked in the forum can be solved with a few searches.

  12. Notepad++. At one point or another we need to work with text files. I highly recommend all developers to use a good text editor that shows the encoding, the end of line characters and other important features. https://notepad-plus-plus.org/
 
Last edited:

Dave O

Well-Known Member
Licensed User
Longtime User
>Avoid calling DoEvents
I used to call this frequently, mainly when I was trying to get the UI to update (e.g. coaxing ProgressDialogShow to appear), but I've been trying to weed it out by replacing it with CallSubDelayed.

#8 (Starter service and declaring globals)
This is the one that I think many of us need to go back and clean up. I get occasional "not initialized" errors and I'm sure this is the cause.

A good kick in the pants for beginners and veterans alike. Thanks Erel!
 
Last edited:

Toley

Active Member
Licensed User
Longtime User
Those tips are really helpfull. I am not a full time android programmer so each time I want to create something, I have to learn a lot of new features.

When you say:
2. Public (process_global) variables should be declared and set / initialized in Service_Create of the Starter service.
What about timers? Is it means that timers should be initialized in Starter Service?
 

Informatix

Expert
Licensed User
Longtime User
Just two comments:

  1. Strings are made of characters not bytes. Don't try to store raw bytes as strings. It doesn't work. Use arrays of bytes instead. The proper way to convert bytes to strings is with base 64 encoding or ByteConverter.HexFromByte
If the array of bytes contains a string (e.g. a message encoded with a charset), the function to convert it is BytesToString(MyArray, 0, MyArray.Length, MyCharset)). If the array of bytes does not contain a string (like the contents of a binary file, e.g. a bitmap), the conversion to string as suggested by Erel is only required if you want to display the array contents (e.g. in hexadecimal format) or use functions that does not accept an array of bytes. In the other cases, the conversion to string is useless.

  1. (B4A) Use services, especially the Starter service. Services are simpler than Activities. They are not paused and are almost always accessible.
    Three general rules about global variables:
    1. All non-UI related variables should be declared in Process_Globals.
    2. Public (process_global) variables should be declared and set / initialized in Service_Create of the Starter service.
    3. Activity process globals should only be initialized if FirstTime is true.
It should be explained when to use a service because, as a general rule, that sounds a bit weird. A service does not replace an activity. A service has no user interface and is mainly useful to perform a task independently of the activities (e.g. playing an audio file whatever activity is displayed). It is run in the same thread as the activities, that's why it's sometimes better to use a different thread than a service (e.g. when you want to access a disk or a network, or when you want to take advantage of multi-cores CPU).
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
It should be explained when to use a service because, as a general rule, that sounds a bit weird
The main point of this message is that developers should not "be afraid" to use services because they aren't familiar with this concept.

Note that in most cases developers should avoid using the Threading library. Libraries should take care of handling long tasks. For example all the official network related libraries will never affect the main thread.
 

LucaMs

Expert
Licensed User
Longtime User
Very helpful, Erel, thank you (I don't know why I found this thread only now, casually - I read ever new posts!)

If you or other people have other suggestions, I would say that they should be added to the first post.

---

I will give MQTT as a good example. I wasn't familiar with this technology. When I started learning about it I was a amazed to see how easy and powerful this solution.
I'm (almost, as always :)) sure about this but age and especially memory brain does not allows it to me... grrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr

Nature is unfair: you have several terabytes of memory, I just few Kb!
 

DonManfred

Expert
Licensed User
Longtime User
Re: item number 4, I'm too busy learning the old things to be afraid to learn new things.
You´ll miss some nice new features then
 

cambopad

Active Member
Licensed User
Longtime User
Very useful tips! Thanks for sharing!

Number 2: I am experiencing it right now :)
 

ValDog

Active Member
Licensed User
Longtime User
Regarding DoEvents - some time ago I was having difficulty getting SelectAll to work when FocusChanged on an EditText. Somewhere in this forum I got the suggestion to use the following coding:

Sub edtDataStg_FocusChanged (HasFocus As Boolean)
If HasFocus Then
DoEvents
edtDataStg.SelectAll
DoEvents
edtDataStg.SelectAll
End If
End Sub

And it has worked fine ever since - so is this usage a concern?
 

Derek Johnson

Active Member
Licensed User
Longtime User
Can you make this a sticky thread please? I too only just found it by accident. It would also be useful if it was a sticky thread in the B4J and possibly other forums as well.
 

Bob Spielen

Active Member
Licensed User
Hello, masters!
Maybe you can help me. When I develop apps I need an overview of the hole code. Kind of a flip chart. Can someone maybe suggest me a type of a CAD program where I can paste the code snippets? And so have an overview of the functions as a whole, as on a map?
In advance I really thank you very much for your kindness!
 
Top