Android Tutorial Embedding files in compiled libraries

Erel

Administrator
Staff member
Licensed User
It is possible to embed files directly in the compiled libraries by following these steps:

1. Add the attached class module, JarFileLoader, to your code (Project - Add Existing Module).
2. JarFileLoader can either load files from the Files folder or from the compiled jar.
While you develop the library you should initialize it and set it to load files from the assets folder:
B4X:
Sub Process_Globals
   Private jfl As JarFileLoader
End Sub

Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
     jfl.Initialize(True) '<--- True = from assets folder, False = from jar file
   End If
   Activity.SetBackgroundImage(jfl.LoadBitmapFromJar("smiley.gif"))
End Sub
3. Before you compile the library you should make sure to change jfl.Initialize(True) to jfl.Initialize(False).

4. The files from the Files folder will not be included automatically in the compiled jar. You need to compile the library and then open the jar file with a program such as 7zip and copy the files to the jar.



The files names are case sensitive. It is recommended to use all lower case names as the IDE will automatically lower case the names when you add the files to the Files tab.
 

Attachments

margret

Well-Known Member
Licensed User
I did this a little different and have no code in the Activity and this works great !!! Thank You:)
 

Erel

Administrator
Staff member
Licensed User
Great. The activity code is only an example. In most cases the calls will only happen inside the compiled modules.
 

Erel

Administrator
Staff member
Licensed User
This is already supported now. Or do you mean that the files will be added to the jar file automatically and File.DirAssets will be replaced with the "resource as stream" method?
 

NJDude

Expert
Licensed User
Right, say that I create a library and then using the B4A IDE I do "Compile to Library", instead of adding that class an option to "Embed files" is present, I think it would be more convenient that way.
 

Erel

Administrator
Staff member
Licensed User
It might be added in the future, though it is more complicated than it may seem, especially with layout files and layout images.
 

Wien.Mart

Member
Licensed User
Hi All,

Is this an easier way to use jar files from third parties or is this for files like photos and music only?

Thanks,

Martin
 

Wien.Mart

Member
Licensed User
Thanks Erel. I read somewhere in the forums that I need to create a wrapper for this. I'm don't have experience with Java so I'm looking for an easier way to do this ... ☺
 

LucaMs

Expert
Licensed User
I get a strange error.

The library that I created contains some image files. The project that uses it works perfectly, it displays the images, but opening it in IDE a message appears which indicates that can not find the files.

In addition, the log says "file not used - warning #15" for each image file


[SOLVED]
 
Last edited:

andrewj

Active Member
Licensed User
Hi Erel,
I want to use this method, but my existing code uses bitmap.InitialiseSample() which takes a directory and a filename as the first two params. How can I use the JarLoader in this case?
Thanks
Andrew
 

Erel

Administrator
Staff member
Licensed User
You will need to first copy the file to a standard location.
Add this code to JarLoader module:
B4X:
Public Sub LoadBitmapSampleFromJar(FileName As String, Width As Int, Height As Int) As Bitmap
   If File.Exists(File.DirInternalCache, FileName) = False Then
     Dim out As OutputStream = File.OpenOutput(File.DirInternalCache, FileName, False)
     File.Copy2(LoadFileFileFromJar(FileName), out)
     out.Close
   End If
   Return LoadBitmapSample(File.DirInternalCache, FileName, Width, Height)
End Sub
 

andrewj

Active Member
Licensed User
Thanks, Erel.

I suggest a refinement to the technique which you might want to make the standard recommendation.

First I added a new method to JarFileLoader based on the code you provided, but all it does is manage the cacheing:
B4X:
Public Sub AssetFromJar(FileName As String) As Boolean
Try
    If File.Exists(File.DirInternalCache, FileName) = False Then
        Dim out As OutputStream = File.OpenOutput(File.DirInternalCache, FileName, False)
        File.Copy2(LoadFileFileFromJar(FileName), out)
        out.Close
        Return True
      Else
        Return True    ' File OK anyway
    End If
Catch
    Log("Failed to copy file to Assets: " & FileName)
    Return False
End Try
End Sub
Then I create a new library project (MediaControllerResources to go with my MediaController library), and added the JarFileLoader code to that one, compiled it to a library, and added all the resource files to that secondary library. The purpose of this strategy is that the code of this lib will rarely or never change, so you don't have to keep re-adding the resources every time you re-compile the main lib.

Then in the main lib I just have to change any reference to a file from Dir.Assets to code like the following:
B4X:
jfl.AssetFromJar(sImage)
bmpBitmap.InitializeSample(File.DirInternalCache, sImage, iButtonSize, iButtonSize)
This way I can keep compiling the lib as often as I want, and all I have to do is occasionally add any new resources straight into the "Resources" jar.

Andrew
 

NJDude

Expert
Licensed User
Is there a way to also load 9Patch with this code?, especially, if you compile to library.
 

NJDude

Expert
Licensed User
Thank you Erel, but, how would I use that?, after the .jar is created? (I'm trying to embed 9patches on a library created with B4A).
 

Erel

Administrator
Staff member
Licensed User
Try to run aapt as described in this blog and then embed the output of aapt instead of the original images.
 

NJDude

Expert
Licensed User
I followed the instructions and embedded the png (just like the link above suggests), it didn't work, so I guess I'm doing something wrong, some guidance will be appreciated. I think this is beyond my pay rate :D
 
Last edited:
Top