B4J Question How to do "background" stuff in B4J without affecting UI?

ByteCounter

Member
Licensed User
I am programming a Point Of Sale application using B4J which also communicates with remote devices via direct socket connection (using jNetwork and opening/using a ServerSocket connection). I want to use the open socket connection like a serial port, receiving queries from remote devices and sending data back)

I am storing POS data in a SQLite database (using jSQL / #AdditionalJar: sqlite-jdbc-3.7.2).

The active "front end" of the application is a typical POS interface, select products, change qty etc.

But I would like to have the communications / processing for remote devices occur in the "background" while the user operates the POS front-end.
As an example, the remote devices may send some kind of query request at any time (via Socket) and require a response from the POS (which typically involve the POS checking data in the SQLite database).
(If it makes things easier I can adjust remote devices to connect only when they make a request).

So my questions are:

1. How can I implement "background" receive, processing and send with B4J? (generally speaking, especially without pausing the front/main code)

2. Is there another way to implement background communications that is better than using direct socket communications? (The reason why I am using direct socket is that remote devices may be Arduino etc so don't want to make things too complex or use a lot of large libraries - some Arduinos like Nanos don't have much RAM / Flash memory). I am not using WebSockets because neither side is a browser (and also because I don't fully understand them).

3. Searching for "B4J background" only seems to bring up threads like https://www.b4x.com/android/forum/threads/server-background-workers.73269/#content
which is about jServer library. I don't know if background workers can only be done with jServer or if I can implement some sort of background function another way.

Thanks
 

Erel

Administrator
Staff member
Licensed User
The answer depends on the specific task you need to do.

Network communication is always done on the background, assuming that you are using AsyncStreams.
SQL - Use the async methods with Wait For.

1. No need to do anything special.
2. There are many options. Most of them are listed here: [B4X] The Networker's Guide To The Galaxy
3. You don't need to and shouldn't use background workers.
 
  • Like
Reactions: DMW

ByteCounter

Member
Licensed User
Network communication is always done on the background, assuming that you are using AsyncStreams.
SQL - Use the async methods with Wait For.

1. I understand that network stuff is done in the background, but what about the event that handles the receive (i.e. Astreams_NewData)? If the program is "busy" doing something else at the moment, the current code/event will have to complete before _NewData is triggered/executed, correct?

2. Any way to get _NewData to operate on another thread? (I worry about main being busy in a loop or something time consuming and unable to handle NewData)

Thanks
 

ByteCounter

Member
Licensed User
1. Yes. What are you doing in that event? How long does it take? You should measure it.

2. No.

If the event sub is implemented properly then it won't be an issue.
Thanks.
Just to clarify some things:

1. It is possible that I may be writing data to a table (i.e doing the front-end POS stuff like when products are sold) but I will also need to read/update data from same table when the remote device send commands back to the POS B4J app. I was planning to put database read/update code in the Asyncstreams_NewData event (since that code runs when the data from remote device is received). Does this sound feasible?

2.Do you have any ideas how to prevent possible contention between both sets of code from doing database access? I can't create another SQL connection and connect to the same (SQLite) database that is already open, right?

3. I just thought about it and am wondering if contention will be a problem... Since the _NewData event does not fire until after (whatever code that is running) finishes it should be OK for both code sections to use same SQL connection and do whatever they need to? No data corruption can occur since both sets of code don't actually run at the same time?

Thanks
 

KMatle

Expert
Licensed User
I have simmilar apps. One as a server with SQlite and network/asyncstreams. All clients (B4A & B4J) connect to it. It's fast as hell. Never had issues. Parallel access isn't a thing as all is handled automatically.

Just test it. Set a timer and put some "pressure" on it. I use my older phones and tablets to generate traffic.
 

ByteCounter

Member
Licensed User
Just to make sure I have things clear:

1. There is an internal message loop that runs and handles program events (your event code) but also "Internal" stuff such as Async events as well as resumeable sub stuff (Wait For/Sleep) transparently in the background without interfering with your code.

2. As long as you don't use modal dialogs or non-async methods main program execution will not freeze (for example, pause while the modal dialog is open or a non-Async SQL query executes).

3. Anything else that I have missed?

thanks
 

ByteCounter

Member
Licensed User
Sorry to keep sounding like a broken record, but I need some more advice.

1. I am starting to feel that an "all in one" B4J app doing both (POS interface front-end) as well as back-end (SQLite database and reply to remote devices) may not be the best design. For example, if the front-end has a login screen or various "confirm?" (modal dialogs) then this will stall (pause) the back-end stuff until user responds, correct?

2. Can I have two separate Java UI apps (running on the same PC) instead for division of tasks? How would I handle communications between the POS front-end app and the other app handling database and network reply?
The only thing I have found is https://www.b4x.com/android/forum/threads/communication-between-ui-and-non-ui-app.54548/#content which seems to indicate that you use either a TCP/IP or UDP communication to communicate.
So I guess this would be something like
UI front-end app connects to other UI back-end app at UDP port 2000
UI back-end app opens ServerSocket on TCP/IP port 3000 for remote network devices to connect to it. It also listens on UDP port 2000 for communication with front-end). (UI could be used to display status screen)
UDP ports used since both are running on same PC and no need for extra TCP/IP overhead?
Is there any other way to have 2 different apps communicate with each other? (I have seen https://www.b4x.com/android/forum/threads/b4x-the-networkers-guide-to-the-galaxy.68974/ )
The only disadvantage here is that testing/debugging both is more complex. However since it seems that you can have more than one instance of B4J open I guess you could work on both in separate B4J windows?
 

Erel

Administrator
Staff member
Licensed User
I am starting to feel that an "all in one" B4J app doing both (POS interface front-end) as well as back-end (SQLite database and reply to remote devices) may not be the best design. For example, if the front-end has a login screen or various "confirm?" (modal dialogs) then this will stall (pause) the back-end stuff until user responds, correct?
1. No. Not correct. Modal dialogs do not block. However you shouldn't use them for other reasons. Use non-modal dialogs instead.
Check the new XUI Views library for a nice and powerful dialogs.

2. I don't see any reason to choose such complex solution.
 

ByteCounter

Member
Licensed User
1. No. Not correct. Modal dialogs do not block. However you shouldn't use them for other reasons. Use non-modal dialogs instead.
Check the new XUI Views library for a nice and powerful dialogs.
Thanks Erel. XUI Views (https://www.b4x.com/android/forum/t...ss-platform-views-and-dialogs.100836/#content ) is new, so I must have missed it.

Part of my confusion is that most of these dialog libraries do not clearly state whether they are modal are not. Maybe add a note to 1st post?
 
Last edited:
Top