Android Question How to access code in B4XMainPage from the Starter service?

RB Smissaert

Well-Known Member
Licensed User
Longtime User
I would like to log application errors to SQLite from this Starter code:

B4X:
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean

End Sub

All my SQLite related code is in my B4XMainPage, but I understand that that is not accessible from the Starter service.
In fact strange things happen in the IDE when I try, eg coding like this:

B4X:
Dim cMP as B4XMainPage

This will show a wavy red line at that code line and when moving the mouse over that I get in the IDE log:
[IDE message - 10:59:02]
An error occurred.
'=' is an unexpected token. The expected token is ';'. Line 1, position 114.

I have a SQLite connection class but that is not accessible either from the Starter service.

So, how do I log to the error to SQLite?
One option is to log to KVS instead, but I would prefer directly to SQLite.

RBS
 

DonManfred

Expert
Licensed User
Longtime User
You can not access ui-elements from within a service.

You can call a sub in mainactivity (callsub/callsubdelayed) and here you can access the B4XPagesManager....
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
You can not access ui-elements from within a service.

You can call a sub in mainactivity (callsub/callsubdelayed) and here you can access the B4XPagesManager....
Thanks, will give that a try.
I take it you mean something like this (but then with argument(s)):

B4X:
CallSub("Main", "Testing")

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
B4X:
CallSubDelayed(B4XPages.GetManager.MainPage, "SubName")

(It is always better to write the source that accesses the database in a class or code module).
OK, thanks for correcting, I thought DonManfred referred to Main.
What is wrong accessing the DB from B4XMainPage (via a connection class)?
After all B4XMainPage is a class as well.

RBS
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
What is wrong accessing the DB from B4XMainPage (via a connection class)?
After all B4XMainPage is a class as well.
It is always better that each object has its own functionality; the purpose of the B4XMainPage is not to directly manage a database and often Views and ResultSets are intertwined in some Subs. Furthermore, a class dedicated only to database operations can be reused in projects with a totally different graphical interface (for example an HTML page).
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
It is always better that each object has its own functionality; the purpose of the B4XMainPage is not to directly manage a database and often Views and ResultSets are intertwined in some Subs. Furthermore, a class dedicated only to database operations can be reused in projects with a totally different graphical interface (for example an HTML page).
OK, fair enough.
What would you call the main purpose then of B4XMainPage?

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
You can not access ui-elements from within a service.

You can call a sub in mainactivity (callsub/callsubdelayed) and here you can access the B4XPagesManager....
That is all working nicely now, using CallSub2:

In the starter service:

B4X:
'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    LogError(Error.Message, StackTrace)
    Return True
End Sub

Sub LogError(strErrorMsg As String, strStackTrace As String)
    
    Dim arrError(3) As Object

    arrError(0) = DateTime.Now / 1000 'as we need seconds, not milli-seconds
    arrError(1) = GetErrorSubFromStackTrace(strStackTrace)
    arrError(2) = strErrorMsg
    
    CallSub2(B4XPages.GetManager.MainPage, "LogAppError", arrError)
    
End Sub

Sub GetErrorSubFromStackTrace(strStackTrace As String) As String
    
    Dim iPos1 As Int
    Dim iPos2 As Int
    
    iPos1 = strStackTrace.IndexOf(Enums.strPackageName) + Enums.strPackageName.Length + 1
    iPos2 = strStackTrace.IndexOf2("(", iPos1)
    
    Return strStackTrace.SubString2(iPos1, iPos2).Replace("_", "")
    
End Sub

Enums.strPackageName is set like this:

B4X:
    Private Reflector1 As Reflector
    Enums.strPackageName = Reflector1.GetStaticField("anywheresoftware.b4a.BA", "packageName")

Note that we need CallSub2 and not CallSubDelayed2 as that doesn't log the error, maybe because by the time
the logging should run (writing to SQLite) the app has fully crashed or the DB connection has gone.

RBS
 
Upvote 0
Top