B4A Library Threading library

This library lets you run Basic4android Subs on separate threads to the main GUI thread. It also contains a Lock (semaphore) object that can be used for resource access arbitration and thread synchronisation.

Included is also an enhanced Exception object to give more information on any Exception caught. This can also rethrow those caught Exceptions and can create new Exceptions to throw.

EDIT :- Version 1.1 posted. See post #13 for details.
 

Attachments

  • Threading1.1.zip
    19.2 KB · Views: 7,226
Last edited:

Informatix

Expert
Licensed User
Longtime User
In most cases you will not see any effect when you change the thread priority.

If I set it to 4 before the thread is started, that works well. The thread runs slower than the main UI thread and I keep the UI responsive. I'd like to change this when the user does nothing, then reverts to a lower priority when the user interacts with the app. With most OS, you just have to set different priority values, but that does not seem to work here (the value is not taken into account after its initial setting). How can I achieve my goal ?
 

Informatix

Expert
Licensed User
Longtime User
What is this thread doing? Many libraries in Basic4android use many threads and the UI is kept responsive.

My goal:
I want to speed up the loading time of a Scrollview and reduce its memory consumption. This ScrollView is loaded with a lot of images. I know all the algorithms to do that (and you implemented some of them in your TableView), but I have a hard time to code that with B4A like it should (i.e. not in the main thread). A few things are not working as expected. I have two threads: one is processing the bitmaps to fill a cache, the other fills the Scrollview on demand, getting data from the cache. The second is so slow that I cannot really use it (even with bitmaps in memory). It seems it has the lowest priority whatever priority I set under 5. If I set its priority to 5, the UI is no more responsive.
I realized by monitoring my phone activity that my app, despite the fact it was idle from an user point of view, was in fact very active. I suppose that's due, in my case, to the garbage collector. But the GC should have a lower priority than my thread. Why does my thread get so little CPU time when the main thread is supposed to be idle? It runs as expected when priority = 5, but it blocks everything else at this level.
My knowledge of Android and B4A is too weak to understand what's going on.
 

Jonas

Member
Licensed User
Longtime User
Can I call subs inside the thread sub without any restrictions?

Like

B4X:
Sub Threadsub
  Dim i as int
  Dim j as int  
  i = i + 1
  j = DoSomeMath(i)
  i = i +j
End sub

Sub DoSomeMath(value as int) as int
  Dim i as int
  i = 0
  i = i + value
  Return i
End sub

I had some error calling some functions in a object, I guess the object tried to update the GUI.
/J
 

avacondios

Active Member
Licensed User
Longtime User
Hi,

When I start a new thread, I am taking the following error from Thread Ended event :
"Exception:Can't create handler inside thread that has no called Looper.prepare()"

My code is the following :

Sub Process_Globals
Dim Thread1 As Thread
End Sub

Sub Button1_Click
Dim args(0) As Object

Thread1.Initialise("Thread1")
Thread1.Name = "B4A Thread 1"
Thread1.Start(Null, "test", args)
End Sub

Sub Thread1_Ended(fail As Boolean, error As String) 'An error or Exception has occurred in the Thread
Msgbox(error, "Thread1 Ended")
End Sub

Sub test
...............
..............
(Network code....)
End Sub
 

Melchor99

Member
Licensed User
Longtime User
Hi all,

This is my first post on this forums, my English is not too well so I'll try to do the best to explain my situation.

I'm using threading library to update in background a SQLlite DB, threads work fine, the updates are performed without any problem in DB but when I press "home button" during the threads are in execution, the threads seems to be destroyed.

How can I prevent this thread destruction when I press "home button"? Is it possible to pause the threads in home button click event?

I've look for a solution in the forums but I haven't find anything. Please, if now exists a solution in the forum for this problem, refer me and I'll check.

Thanks in advance
Regards
 

agraham

Expert
Licensed User
Longtime User
Look at the Thread demo. Its threads survive device rotation and the Home button because they are declared in Process_Globals. You can usually stop a thread with Thread.Interrupt - if it doesn't work then because the thread code is a tight loop then thread itself can periodically check IsInterrupted and return if it is set.
 

Melchor99

Member
Licensed User
Longtime User
Thanks, I'll try to declare the threads as Process globals, now the threads are defined as Globals in the activity.

If it doesn't work, I'll try to interrupt the threads in home button click event and undo it in the resume.

Thanks.
 

Melchor99

Member
Licensed User
Longtime User
Hi,

First of all thanks for your answer,

I've tried to follow the demo and your recommendation about to put Thread declaration as Process globals, but still have the same problem, when I press home, the threads are destroyed :(

This is my more or less my code:

Sub Process_Globals
Dim Thread1 As Thread
Dim Thread2 As Thread
End Sub


Sub Activity_Create(FirstTime As Boolean)
Dim args(0) As Object

Activity.LoadLayout("LayoutJuego")
p.SetScreenOrientation(1)
Thread1.Initialise ("Thread1")
Thread1.Start (Null, "Juega1", args)
Thread2.Initialise ("Thread2")
Thread2.Start (Null, "Juega2", args)
....
........
End Sub



Sub Juega1
For j=0 to...
Main.SQL1.ExecNonQuery ("INSERT INTO .....")
Next
End Sub

Sub Juega2
For j=0 to ...
Main.SQL1.ExecNonQuery ("INSERT INTO .....")
Next
End Sub


Please, any suggestion about how can I do in order to avoid the threads stop when I press home?

Thanks in advance for your help!
 

agraham

Expert
Licensed User
Longtime User
You can see that threads can run when the activity is paused by running the thread demo while looking at the Log pane in the IDE. Press Start to run the threads then Back or Home. You will see a lot of "Ignoring event ..." messages as the Basic4android event mechanism knows that the activity is paused while the threads are still queuing GUI updates.

Compare your Thread initialisation to that of the demo. You are re-creating the threads every time the activity is recreated so destroying the earlier ones. I know you want to get a lengthy update off the main thread but I am not sure that doing what might be critical database updates in those threads is a good idea as the process the activity is part of might be destroyed by Android without warning taking the threads with it, unless of course another activity of the same process is active. I would put a Begintransaction before the For and an EndTransaction after the Next to ensure that the batch of updates.

However the Thread library originated in the early days of Basic4android. Since then Erel has built asynchronism into the main libraries that benefit from it, like AsyncStreams, so you don't usually need to use your own threads. The SQL library provides asynchronous methods you can use that do it all for you. Look at AddNonQueryToBatch, ExecNonQueryBatch and ExecQueryAsync. They deal with beginning and ending the transaction and call an event on your main thread with a success or failure flag.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
The SQL library provides asynchronous methods you can use that do it all for you. Look at AddNonQueryToBatch, ExecNonQueryBatch and ExecQueryAsync. They deal with beginning and ending the transaction and call an event on your main thread with a success or failure flag.
I highly recommend you to use these methods. They will "solve" the difficult parts for you.
 

westingenieria

Active Member
Licensed User
Longtime User
It is possible to start a new thread in a timer? The timer run every 30 seconds... Sometimes i have errors like "Only the original thread that created a view hierarchy can touch its view" or "IndexOutOfBounds"

Example:
B4X:
Sub Timer1_tick
      Dim args(0) As Object
      Thread.Start(Null,"Thread_Sub",args)
End Sub

Thread_Sub
      .....
      .....
End Sub
 
Top