Jump to content
Stewag

Styles bloating final packages

Recommended Posts

Posted (edited)

I develop a smartphone app for Android and iOS. In that, I use a stylebook and added Android, iOS and Windows styles to the master form (Windows only for development).


Recently I found out, that the styles for other OS are also included in Android .apk and .aab packages!

 

Here are the sizes of my Android packages. I deleted one style after the other, and the package got considerably smaller each time :
.apk (Android development):
Android, iOS and Windows styles: 15.2 MB
Android and OS styles: 14.2 MB
only Android style: 13.2 MB


.aab (Android store):
Android, iOS and Windows styles: 25.0 MB
Android and OS styles: 14.2 MB: 23.1 MB
only Android style: 21.3 MB

 

I haven't tested yet if iOS .ipa is handled the same way.

 

I would have expected, that styles of other OS would simply be ignored.

Now I learned, that I can reduce the size of the store package by 15% simply by deleting other styles prior to compilation😯

 

This seems to be a major bug, isn't it?

 


 

Edited by Stewag

Share this post


Link to post

Hi

 

The things you do in the form editor is embed as a resource in the programs. If you fill your styles with more than one platform they are all embed in it.

 

The solution is to use TDataModule as a TStyleBook container. One per platform or per platform/style. In the TDataModule unit, simple use compiler defines to compile or not the data module class depending on MSWINDOWS, ANDROID, IOS, MACO or LINUX defines. Condition the implementation the same way you do for the interface.

 

In your code, do the same for the uses of these units and of course to enable or not the styles you want to use.

 

It's a little work but it's easy to do and avoid having too big EXE/APK/IPA/APP files.

Share this post


Link to post
Posted (edited)

Hi Patrick,

 

this sounds workable, I will try it. Thank you!

 

Still I am puzzled as I don't think that many programmers are aware of this "style-addup". At least I never read about it. 

Even in Emba's "screens" code samples in GetIt, various styles are just added to the main form (screenshot).

 

This seems to be a poorly documented topic?

 

 

LoginForm GetIt Code Sample.jpg

Edited by Stewag

Share this post


Link to post

I've just created a sample project to illustrate what you can do. Check https://github.com/DeveloppeurPascal/Delphi-samples/tree/main/FireMonkey-Samples/027-StylesAndEXESize

 

Screen samples are good for understanding how to use visual component stacking, layout and alignment, but not necessarily for organising things.

 

Never put styles on forms but rather on data modules, like database components or image lists used by several files. This is something you learn as you use it, which you can read about in certain corners of the documentation or in the many books full of good practices. Unfortunately, it's difficult to add a comment in the examples, but a good idea for improvement.

  • Like 2
  • Thanks 1

Share this post


Link to post

I used TStyleManager for style control and added the .styles files to the resource. However, this increased the size too much and I want to include multiple styles. So I embedded compressed zip files instead. Each style became ~15% of its original size. It is also not difficult to handle:

// modified from my code, not tested but should work
function LoadZippedStyleFromResource(const ResName, Filename: string): TFmxObject;
var
  rs, ms: TStream;
  ZipFile: TZipFile;
  ZipHeader: TZipHeader;
begin
  try
    rs := TResourceStream.Create(HInstance, ResName, RT_RCDATA);
    ZipFile := TZipFile.Create;
    try
      ZipFile.Open(rs, zmRead);
      ZipFile.Read(Filename, ms, ZipHeader);
      try
        ms.Position := 0;
        Result := TStyleStreaming.LoadFromStream(ms);
      finally
        ms.Free;
      end;
    finally
      ZipFile.Free;
      FreeAndNil(rs);
    end
  except
    FreeAndNil(rs);
    Exit(nil);
  end;
end;

// used like this
 Style := LoadZippedStyleFromResource('Polar', 'PolarDark.style');
 if Assigned(Style) then TStyleManager.SetStyle(Style);

 

Share this post


Link to post
Posted (edited)
Quote

So I embedded compressed zip files instead. Each style became ~15% of its original size.

Thank you Wak, but this is somewhat complicated and still not as effective as the procedure, that Patrick suggested.

 

I implemented it now as follows:

- remove stylebooks from all forms

- add new Datamodules, one for each OS (DatamoduleAndroid, DatamoduleiOS, DatamoduleWindows)

- put a stylebook with an OS-specific style on each of the datamodules

- set UseStyleManager property on all stylebooks to true, to ensure that the style is valid for all forms

- add this code to .FormCreate of each form:

{$IFDEF MSWINDOWS}
  if not assigned(DataModuleWindows) then
    DataModuleWindows := TDataModuleWindows.Create(self);
  Stylebook := DataModuleWindows.StyleBook1
{$ENDIF}
{$IFDEF ANDROID}
  if not assigned(DataModuleAndroid) then
    DataModuleAndroid := TDataModuleAndroid.Create(self);
  Stylebook := DataModuleAndroid.StyleBook1
{$ENDIF}
{$IFDEF IOS}
  if not assigned(DataModuleiOS) then
    DataModuleiOS := TDataModuleIOS.Create(self);
  Stylebook := DataModuleiOS.StyleBook1
{$ENDIF}

- and this to uses:

{$IFDEF IOS}
  DMIOS,
{$ENDIF}
{$IFDEF ANDROID}
  DMAndroid,
{$ENDIF}
{$IFDEF MSWINDOWS}
  DMWINDOWS,
{$ENDIF}

This totally prevents bloating of packages with foreign styles and reduced my package size more than 15% 🙂

Edited by Stewag

Share this post


Link to post

I have never used Datamodules and wonder if it is compressed after compilation?

 

Yes, Patrick's method is better because compression is unnecessary for IPA and APK files, which are also Zip-compressed.

For the Mac and Windows apps, compressing them and using conditional resources should help. Including eight styles resulted in a size increase of 965 KB for the Mac app and 3.24 MB for the Windows app. They are 8 MB and 15.5 MB without compression.

{$IFDEF MSWINDOWS}
{$R 'Styles\Polar.Win.res'}
{$ENDIF}

{$IFDEF MACOS}
{$R 'Styles\Polar.Mac.res'}
{$ENDIF}

 

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×