Android Question If Library

AHilton

Active Member
Licensed User
Longtime User
I'm writing some generic utility subs to be used in various apps and would like to test for the existence of libraries being loaded before dim'ing an object from them. Something like this ....

If ServerSocket then
Dim Server as ServerSocket
[Rest of the routine]
End If

Anything like that?
 

Roycefer

Well-Known Member
Licensed User
Longtime User
I don't think you'll be able to compile code that references an object in a library that isn't added to the project. I don't think this issue would often reach a run time exception. But if it did, you could use a Try/Catch block to test for the presence of library. Dim an object from that library in the Try part and Catch the ensuing Exception if that library isn't added to the project. But, like I said, I'm not sure how you'd test this since you won't be able to compile without adding the necessary library to the project. The only way I can see running into this problem at run time is if you are using Reflection or JavaObject to Dim an object from a library that hasn't been compiled with the app.
 
Upvote 0

AHilton

Active Member
Licensed User
Longtime User
I think that you should use a conditional compilation symbol for this.
B4X:
#If SERVER

#End If


While that would work, it would require more than a dozen symbols (equaling the libraries referenced) just for what utility code I have so far in that module. Is this something I can post as a "Wish" or is it just unreasonable to expect?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Here is a solution. Create a class named ClassChecker with this code:
B4X:
'Class module
Sub Class_Globals
   Private CheckedClasses As Map
End Sub

Public Sub Initialize
   CheckedClasses.Initialize
End Sub

Public Sub ClassExist(cls As String) As Boolean
   If CheckedClasses.ContainsKey(cls) Then Return CheckedClasses.Get(cls)
   Try
     Dim jo As JavaObject
     jo.InitializeStatic(cls)
     CheckedClasses.Put(cls, True)
     Return True
   Catch
     CheckedClasses.Put(cls, False)
     Return False
   End Try
End Sub

Initialize it in Starter service:
B4X:
Sub Process_Globals
   Public ClassChecker1 As ClassChecker
End Sub

Sub Service_Create
   ClassChecker1.Initialize
End Sub

Now you can check whether a class exists or not.
B4X:
If Starter.ClassChecker1.ClassExist("anywheresoftware.b4a.objects.SocketWrapper.ServerSocketWrapper") Then
 ...
End If
 
Upvote 0

AHilton

Active Member
Licensed User
Longtime User
That doesn't help in what I'm talking about. To continue the last bit of code you posted above...

B4X:
If Starter.ClassChecker1.ClassExist("anywheresoftware.b4a.objects.SocketWrapper.ServerSocketWrapper") Then
     Dim Svr1 as Server Socket       ' Throws a warning of "Unknown type: serversocket" and, obviously, doesn't compile because (see next paragraph)
     Svr1.Initialize(0,Null)
End If

The Networking library isn't loaded in this particular project. And doesn't need to be in this project. It isn't used. So, you're asking yourself: "Self, then why include the code that calls this library?" It's because this code is just a small utility sub along with a whole lot of other utility subs in a shared code module that gets used between several projects. If I don't need the Networking library in this project, then why include it (I'd be including a dozen libraries in every project that's likely not needed)? That shouldn't mean I have to have multiple shared code modules depending on which combination of libraries that are loaded in a given project.

Any way to tell if a library is loaded and have the compiler ignore the references from code?

As in ...

B4X:
If ServerSocket then
     Dim Server as ServerSocket
     ...
End If

... or ...

If LibraryLoaded("ServerSocket") then
     ...
End IF

I'd even take an #ignorewarnings for this and let it compile even though the library doesn't exist in the project.


My alternative is to create shared code modules based on libraries (ie: Network.bas, Audio.bas, Animation.bas, etc.) instead of just one shared code module. It'd sure be nice to just have a single call to see if a library is loaded, though.
 
Upvote 0

Roycefer

Well-Known Member
Licensed User
Longtime User
What are you doing with your objects in your utility module? If you're not doing stuff that's too complicated, you could do it all with Reflection or JavaObject. For example:
B4X:
If Starter.ClassChecker1.ClassExist("anywheresoftware.b4a.objects.SocketWrapper.ServerSocketWrapper") Then
   Dim jo As JavaObject
   jo.InitializeNewInstance("anywheresoftware.b4a.objects.SocketWrapper.ServerSocketWrapper", Null)
   jo.RunMethod("Initialize", Array(port, "eventname"))      '<--This will be "_initialize" instead of "Initialize" for certain objects. You'll have to check.
   'do more stuff
   'if you have to return a ServerSocket from a public method, return it as an Object
End If

This will compile and it shouldn't throw any java.lang.RuntimExceptions if the Network library isn't loaded because you'll never get to the jo.InitializeNewInstance line. Of course, if you're doing a lot of complicated stuff, doing it all in JavaObject or Reflection will be pretty tedious. But it will still work.
 
Upvote 0
Top