There are few different ways to do this. If you want to raise an event sub in the Main thread from a non-Main thread, your best bet is to call ba.raiseEventFromDifferentThread(). In this way, the target sub will be executed in the Main thread and can access UI elements and it doesn't matter from which thread it is being called. If you use this method correctly, developers who use your library will be able to use the Sender keyword in their event subs.
You can also use CallSubDelayed which is a member function of anywheresoftware.b4a.keywords.Common. This will follow the normal rules of CallSubDelayed usage. There is no access to the Sender keyword using this method.
If you want to directly call an event sub in a blocking fashion (perhaps you need the return value of the event sub before you continue to the next line) then you will want your event sub to execute in the same thread as that from which it is being called. In this case, I use straight-forward Java reflection to call the target sub.
Whichever path you take, make sure to use the @Events annotation. It will make life a lot easier for the users of your library.