Stewag 1 Posted April 7 (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 April 7 by Stewag Share this post Link to post
Patrick PREMARTIN 121 Posted April 8 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
Stewag 1 Posted April 8 (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? Edited April 8 by Stewag Share this post Link to post
Patrick PREMARTIN 121 Posted April 8 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. 2 1 Share this post Link to post
Wak 1 Posted April 8 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
Stewag 1 Posted April 8 (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 April 8 by Stewag Share this post Link to post
Wak 1 Posted Friday at 02:43 PM 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} 1 Share this post Link to post