Android Question "Heavy work" and freezing - multithread?

Mike1970

Well-Known Member
Licensed User
Hi everyone, I've an app that need to download an huge dataset.
We are talking about making a http request the return a json of 8000 rows, that need to be stored in a local SQL DB in the device.

Now.. the problem is the following: downloading and storing all the rows in the DB takes a while, and I don't want the user to wait until the process finishes, because it is not essential, and it could become long.
So the logical solution is: "do it in background" ok... It is what I want to do, but even if I avoid to use the "wait for" the app still freezes (to prevent freezing I put a "sleep(0)" but it slows down a lot) because is inserting all the rows in the DB.

So.. I think that the right way to do it is entrust the work to a separate thread, in this way it will manage ONLY that part, leaving the rest of the work to the main thread.

The problem at this point is: is possible to use multithreading in B4A? if yes, how?
or maybe this is not the best solution.. I don't know :(

I found this in the forum:

Is this the right way in 2021? or something has changed?

Thanks in advance for you tips
 

Marvel

Active Member
Licensed User
This should solve your problem. Use addquerytobatch to insert records asynchronously. When it's done the NonQueryComplete event will be raised

 

Mike1970

Well-Known Member
Licensed User
This should solve your problem. Use addquerytobatch to insert records asynchronously. When it's done the NonQueryComplete event will be raised

Ouh thanks Marvel, it seems surely a good tip! I will try it tomorrow.

However I'm curious to know if multithreading is a thing here in B4X world. it would be useful also for other things.

Maybe combining your suggestion with a separate thread will be even more effective.
 

Marvel

Active Member
Licensed User
Addquerytobatch should be sufficient.
Erel has advised against multithreading a lot of times. I've never actually tried using multi threading, but I know there is a old lib for it on this forum.
I'm sure you can get it to work perfectly without multi threading though.
 

Mike1970

Well-Known Member
Licensed User
Addquerytobatch should be sufficient.
Erel has advised against multithreading a lot of times. I've never actually tried using multi threading, but I know there is a old lib for it on this forum.
I'm sure you can get it to work perfectly without multi threading though.
Will Addquerybatch raise an event everytime a query is executed?
because given that it will be a "background process", I need to show a progress bar in the UI, and If I don't now how much queries are executed I can't increase the progress to show to the user the state of the "download"..
I take a quick look but as I could see there is only the event to inform that it finished, am I wrong?
 

Marvel

Active Member
Licensed User
I don't think you can get an event everytime a record is added. Why not use an infinite loader with a fancy text like "Grab a coffee while we set you up" or something similar. When the success event is raised, just remove the loader and show a success text.
 

sfsameer

Well-Known Member
Licensed User
I have done data syncing alot in many projects we have built using B4X so for me what really worked was doing a background data sync, and as your question above "how?"
It's very simple, just create a service.
Put your download and insert code in it and start your service.
Once it's started it will work in the background without effecting your UI and the user will not notice any lagg.

If you would like, upload your project and I will set it up for you :)


More information :
 

Mike1970

Well-Known Member
Licensed User
I have done data syncing alot in many projects we have built using B4X so for me what really worked was doing a background data sync, and as your question above "how?"
It's very simple, just create a service.
Put your download and insert code in it and start your service.
Once it's started it will work in the background without effecting your UI and the user will not notice any lagg.

If you would like, upload your project and I will set it up for you :)


More information :
Thanks, yes it was an idea I had too. The thing is that I’ve a Whole class, in a class module.
maybe I will combine the two things
 

sfsameer

Well-Known Member
Licensed User
Thanks, yes it was an idea I had too. The thing is that I’ve a Whole class, in a class module.
maybe I will combine the two things
Always do the "heavy" looping/data collection/Data inserting in a service, this way you will never effect the UI :)
 

LucaMs

Expert
Licensed User
I haven't read the whole thread, just the question, the first post (better, first two lines 😄).

In general, if you have to load thousands of "records", from any source, it is much better to paginate, that is to load N (100?) at a time, as needed.
 

Mike1970

Well-Known Member
Licensed User
I solved using addquerytobatch and keeping all in a class, i tried to put in a service, but i had problem with the WaitFor.
 

Mike1970

Well-Known Member
Licensed User
AddQueryToBatch is the best option. It creates a single transaction and it does everything in the background.

And it is very simple to use.
It is what I did 😌

I just wanted to wrote it clearly, so maybe in the future someone that will have the same problem knows how to solve it 😁😁

thank you all for your help!
 

OliverA

Expert
Licensed User
It's very simple, just create a service.
Put your download and insert code in it and start your service.
Once it's started it will work in the background without effecting your UI and the user will not notice any lagg.
Please note that this is a misconception. By default, Services do not run on a separate thread.
By default, all components of the same application run in the same process
Link: https://developer.android.com/guide/components/processes-and-threads
 
Top