B4J Question How to create an instance of a B4J Class with JavaObject

LucianDesign

Member
Licensed User
Longtime User
I want to create an instance of a B4J Class with JavaObject. I'm using the InitializeNewInstance method to create a new instance, but the B4J class Initialize method is never called.

B4X:
 Dim jo As JavaObject
' jo.InitializeContext 'This is not working in B4J
jo = jo.InitializeNewInstance("b4j.example.myclass",Null)
Log(jo) 'The Initialize method is not executed

To call the explicit "_initialize" method I need the BA object (is this the right approach?)
How to create an instance of a B4J Class with JavaObject?
 

stevel05

Expert
Licensed User
Longtime User
Why do you want to do this? It would be easier to Create the class normally then assign it to a JavaObject, although I am not sure why you would want to.
 
Upvote 0

LucianDesign

Member
Licensed User
Longtime User
Hello,
Yes I know that. But I have a specific use case where I need to create the Instance of a B4J class on the fly. This case is similar to how the AddHandler (method from the Server Class) works.

Example:
B4X:
Public testS As Server
testS.Initialize("")
testS.AddHandler("", "MyClass", True) 'Here we pass the class name that will be instantiated
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Unlike jServer library you only need to deal with a specific set of classes. Create a factory sub that receives the class name and returns a class object:
B4X:
Sub CreateClass(Name As String) As Object
 Dim res As Object
 Select Name
  Case "MyClass1"
    Dim mc1 As MyClass1
    res = mc1
 Case "MyClass2"
   Dim mc2 As MyClass2
   res = mc2
 End Select
 Return res
End Sub
 
Upvote 0

LucianDesign

Member
Licensed User
Longtime User
Hello Erel,
Thanks for the example. The factory method works great if you already know a specific set of classes.
The problem is that I'm building a library, and I need to create an instance of a B4J class that is not bundled in the library. It is in the project.

So ... a method from the lib needs to create an instance of a B4J class from the project.
 
Upvote 0

LucianDesign

Member
Licensed User
Longtime User
Hello,
The library is written with b4j ... I don't know how to use ba.raiseEvent to get a b4j class instance.
My use case is similar to AddHandler (method from the Server Class).

In the lib I have:
B4X:
Public Sub RegisterPage(PageName As String, ClassName As String)
    If Not(LWPages.IsInitialized) Then
        LWPages.Initialize
    End If
    Dim tmpObj As JavaObject
   tmpObj = tmpObj.InitializeNewInstance(Utils.GetPackageName & "." & ClassName.ToLowerCase, Null)
 Log(tmpObj) 'The object is not initialized
 LWPages.Put(PageName, tmpObj) 'We put the object in a Map
End Sub

In a project using the lib ("MyClass" is defined in the project)
B4X:
    'In a project using the lib
    myapp.RegisterPage("mypage", "MyClass")
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Without knowing the full functionality, we could be going round in circles, but from you last post it would be possible to do something like:

B4X:
DIm Class As MyClass
Class.Initialize
myapp.RegisterPage("myPage",Class)

Then in the lib:

B4X:
Public Sub RegisterPage(PageName As String, Class As Object)
    If Not(LWPages.IsInitialized) Then
        LWPages.Initialize
    End If

LWPages.Put(PageName,Class)
 
Last edited:
Upvote 0

LucianDesign

Member
Licensed User
Longtime User
Hello,
Thanks stevel05! Yes! This is another option.
All I wanted is to encapsulate the object creation in the RegisterPage method, but I guess there is no other way.

Thank you all!
 
Upvote 0

jgmdavies

Member
Licensed User
Longtime User
@LucianDesign

I suspect it's possible but I haven't tried in B4J. In B4A I use some inline Java to do this sort of thing (for a unit testing approach), e.g.

B4X:
       Class c = Class.forName("myClass");
       Object o = c.newInstance();

       Method method = GetMethod(o.getClass(), "_initialize");

       Object returnObj = method.invoke(o, processBA);

(where GetMethod is my own, using 'c.getDeclaredMethods()'.)

The B4A 'Initialize' sub is called and I can then use the object as a 'normal' B4A object, e.g. using 'CallSub' to call its other subs.

HTH,
Jim
 
Upvote 0
Top