Android Question Single instance of a class in a module. Craziness?

netsistemas

Active Member
Licensed User
Longtime User
I had a module with all the logic for connecting to a database. In this forum, you have recommended me to take all the logic to a class and use WAIT FOR, which I needed in a module is not possible. The question is can I create a single instance of the class in a module and ALWAYS use that class? I guess I'll have to create an instance of the (dim) class in every activity where I use it, which is going to bring, I'm afraid, future problems. The main problem is that in the class I launch MSGBOX that I want to stop with wait for, but it gives me an error because the msgbox function fails to detect the activity associated with the msgbox.
 

netsistemas

Active Member
Licensed User
Longtime User
Everything I want to do is motivated by this error, which from what I have read, I will not be able to avoid:

..
** Activity (frmmain) Pause, UserClosed = false **
** Activity (frmparteplus) Create (first time) **
GetRecordSet2: SP_GetAPPSelector @Tabla=?, @ValorBuscar=?, @Codigo=?
GetRecordSet2: exec SP_PartesGetDistancias @Lat=?, @Lon=?, @MaxKms=?, @rt_Cuantos=?, @Empleado=?
** Activity (frmparteplus) Resume **
** Activity (frmparteplus) Pause, UserClosed = false **
** Activity (frmselectorparte) Create (first time) **
** Activity (frmselectorparte) Resume **
GetRecordSet2: Select Top 100 * From CN_ParteSqlParaApp Where 1=1 And (Coalesce(Cerrado,0) = 0 or Coalesce(NoFacturable,0) = 0) And Coalesce(Parte , '') LIKE '%2023%' Order by Parte Desc
Error occurred on line: 1570 (clsConexion)
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@f98f2e2 is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:1312)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:405)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
at android.app.Dialog.show(Dialog.java:352)
at anywheresoftware.b4a.keywords.Common.showAndTrackDialog(Common.java:591)
at anywheresoftware.b4a.keywords.Common.Msgbox2Async(Common.java:502)
at anywheresoftware.b4a.keywords.Common.MsgboxAsync(Common.java:464)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:777)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:354)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:205)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
at anywheresoftware.b4a.shell.DebugResumableSub$RemoteResumableSub.resume(DebugResumableSub.java:22)
at anywheresoftware.b4a.keywords.Common$14.run(Common.java:1748)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7872)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)




Apparently this problem occurs because the MSGBOX or MSGBOXASYNC does not detect the activity on which the message must be mounted.
Let's say it's as if it were being launched from a service, which I know you can't do.
To solve this, I was thinking of creating an instance in each Activity, because I don't see any other way to do it.

The program has many activities and before, a single module with the connection that prevents me from waiting for and what's worse, many 'The application does not respond' messages appear and more in android 13. I think that in previous versions, it hangs the program due to this.
That being said, I think I should output the module logic to a class, as Erel recommended.
But now I have this other problem with the MSGBOXASYNC (and the not recommended unsa MSGBOX).
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Keep your class in Starter and provide a callback/event in your class that does the MsgboxAsync thing. Set it when you open an activity that uses your class.

EDIT: Set the callback in Resume in an activity that uses your single instance, clear it on Pause and check in your instance if a callback is set before you call CallSub.
 
Last edited:
Upvote 0

netsistemas

Active Member
Licensed User
Longtime User
thankyou very much!!!


I think I have it resolved, I have a lot of work left to do the set in all classes. If I understood correctly, and I think so, this is the code used:


In Starter:

B4X:
Sub Process_Globals
    Public clsConnec As clsConexion
end sub


Sub Service_Create
    clsConnec.Initialize("Conexion")
end sub




In clsConexion:

B4X:
'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(NombreClaseInstanciada As String )
    mEvent = NombreClaseInstanciada
End Sub

public Sub SetObject(Obj As Object)
    mCallBack = Obj
End Sub


PUBLIC Sub MsgBoxInterno(M1 As String, M2 As String )
    If SubExists( mCallBack, mEvent & "_MsgBox") Then
        CallSub3( mCallBack, mEvent & "_MsgBox",M1,M2)
    End If
End Sub


and finllay in Activities:


B4X:
Sub Activity_Create(FirstTime As Boolean)
        Starter.clsConnec.SetObject(Me)
'...

end sub



sub Activity_Resume

       Starter.clsConnec.SetObject(Me)
end sub       


Sub Conexion_MsgBox(M1 As String, M2 As String )
    MsgboxAsync(M1,M2)
End Sub



Only i do not: 'clear it on Pause'


Why do you think I should do this?

Important, the activity must be established and defined as an object, since Activity cannot be used in a class, the compiler told me.
I leave it written for future people who read this.
 
Last edited:
Upvote 0

netsistemas

Active Member
Licensed User
Longtime User
Is it possible that by taking the database connection class to the STARTER service, my application consumes more battery?

If instead of using it from STARTER, I take this class to a module, would there be any problem?
For the rest, everything is working very well. I've also included asynchronous calls and use of wait for, and it seems to have improved a lot. Android 13 'Close or wait' messages have disappeared where I use asynchronous methods.
This, combined with RETRIES when the connection fails (double reconnect loop), I think makes the app better. (I leave it written for future people who read this)
 
Upvote 0

netsistemas

Active Member
Licensed User
Longtime User
i change to module, without problem (for now all good), BUT.


But the app is still consuming a lot of battery. Perhaps a WAIT FOR is left in some process that makes the application continue working in a process and therefore consuming battery?
Crated other question for this:
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Perhaps a WAIT FOR is left in some process
Nope. That won't happen. Your app is idle during a Wait For unless it is doing something else in which case the Wait For will not be invoked until control returns to the apps message loop.
 
Upvote 0
Top