Android Question How to load .so libraries using inline Java?

JordiCP

Expert
Licensed User
Longtime User
I am starting to play with inline Java code.

I would like to port some functionalities from a java library that I wrote some time ago. This library uses a .so library. In the JAR, these .so files were under a "lib" folder

lib/armeabi/libmysolib.so
lib/armeabi-v7a/libmysolib.so


So I write this in the inline java code, in a similar way as I did in my java library,

B4X:
#if java
   ...
   System.loadLibrary("mysolib");
   ...
#end if

The next step is to add the .so files to the project.

Where must I place the "lib" folder with its content? I have tried DirAssets but it didn't work.

--EDIT-- Also tried copying the lib/armeabi/libmysolib.so and lib/armeabi-v7a/libmysolib.so to File.DirInternal, but no luck
 
Last edited:

JordiCP

Expert
Licensed User
Longtime User
Thank you Erel.

At the end, I succeeded in loading (at least the system didn't crash) the library making a call to System.Load with the absolute path (after copying to File.DirInternal) instead of System.LoadLibrary, but no way to access the functions in it. So, I suppose there must be more things involved.

The purpose was to see if it is possible to integrate the .so file with a minimum Java overhead in B4A, so that each time I modify the C code and compile it, don't have to compile the Java JAR again.
 
Upvote 0

timwil

Active Member
Licensed User
Longtime User
I just got an integrated POS device that includes a printer and RS232 port. The supplier provided two .so files that allows access to them from an Android app. I am trying to understand how to access them. Is there an example of it?
 
Upvote 0

timwil

Active Member
Licensed User
Longtime User
What exactly am I looking for?

I have a few .class files some .java files

I am attaching one of the .java files that seems to be for accessing the serial port
 

Attachments

  • SerialPort.zip
    1.3 KB · Views: 292
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
You need to build a jar file from this java class and the .so file.

The methods naming of the .so file are "linked" to the package and class name of this java file through the NDK. That is why it is not easy to call them directly from B4A
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
In fact, using Inline Java and some tricks, it is technically possible to interface in some cases B4A+Inline java to simple .so files. But I do not recommend it unless you have a strong reason for it, and surely to get it working will give you far more headaches than compiling a jar.

I see 2 different use cases when talking about Inline Java + .so files:
a) B4A+Inline Java + C --> Compile the C file with the NDK (some settings required) and then you have B4A+InlineJava + .so file. I tried it and it worked for me :D
b) B4A+Inline Java + existing .so file .--> Point (1) below will limit you. Also, you must have deep understanding of what functions do.


Here some background of what I have seen so far (maybe inaccurate)

1) As the .so file has been compiled with the JNI interface to be used from a specific java package name and class, the B4A package name and class where you instantiate it, should match these names.
2) The .so files must be placed in the Files folder of yor B4A project before compiling. But as libraries cannot be directly instantiated from File.DirAssets, they will have to be copied to File.DirInternal and then loaded with System.Load()
3) Also, if there are different .so file versions for different architectures (armeabi, armeabi-v7, ...) you will have to determine by code which is the appropiate for your device. If you only have one file, I suppose it will be for all ARM devices. The reason for this is that System.LoadLibrary() decides for you which is the right version for your device architecture. As this function did not work for me (I think it only looks for the files at predefined paths and don't know if they can be changed), I used System.Load() but it loads a specific file, so you must know which is the one you need.


If you are still interested, I will post tomorrow (too late for me now) a small example of case (a) and try to see if (b) can work in this case taking into account (1)
 
Upvote 0

timwil

Active Member
Licensed User
Longtime User
@JordiCP - Any luck with that example?

I have been able to get my new toy to print using the RS232 sample (found here somewhere). What I need still is to have the .so library that turns the printer on. It is a simple activatePrinter() function in the native library. So the inline would seem to be way to go instead of building a library and all that.
 
Upvote 0

timwil

Active Member
Licensed User
Longtime User
here are two files - the .so library and a .java source that accesses it
 

Attachments

  • poslib.zip
    3 KB · Views: 322
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
Sorry, I tried but haven't been able to set it up, since there are some naming conventions in the package and module name which cannot be set to be compatible with the JNI interface

I think that at the end you will need to build the wrapper library o_O
 
Upvote 0

timwil

Active Member
Licensed User
Longtime User
OK thanks for trying.

I have been trying to get my head around exactly how to do that but up to now can't quite get it
 
Upvote 0
Top