Hello,
Does size matter? We may never find the answer to this eternal question but when it comes to APKs I believe it does.
Project structure and contents.
My Xamarin Forms project is fairly small, simple and straightforward. One solution, with two projects: the .NET standard library and the application for Android. No iOS, No UWP. I am using Visual Studio 2019 Professional (version 16.2.2).
Both the projects reference Xamarin.Forms
(4.0.0.425677) and Xamarin.Essentials
(1.2.0).
The standard library project contains the Application class and two XAML content pages. The first is the splash page which shows a PNG (11.5KB) saved as a drawable resource in the Android project. The second is just a WebView which displays a site from the internet. There is also the application icon PNG (3.09KB) saved as a drawable resource in the Android project. The Android project contains one activity class. No layouts, no assets and no other drawables except for the two mentioned above.
Android manifest and options.
The minimum android version is 4.1 (API 16) and target is 9.0. I've set ProGuard as the Code shrinker and linking the Sdk and User Assemblies (I've also tried with Sdk Assemblies Only with no difference). No Shared Runtime, no One package per ABI (I am supporting only armeabi-v7a), no incremental packaging and no multi-dex. The selected configuration is the Release configuration.
The size of the APK.
The generated APK is 22.170KB in size. When signed it grows to 22.232KB. When I zip the APK it shrinks straight down to 10.778KB. The APK generated by Android Studio for the exact same project written in Java is 1.800KB in size.
This is quite a big APK given the project structure and contents described above, isn't it?
Is there anything I can do to produce a smaller APK?
@Jarvan Nope. Nothing.
Thanks for the links but they provide no real solution.
An empty Xamarin.Forms project results in a 20+ MB APK with Sdk linking and code shrinking enabled.
As far as I can tell, the embedded assemblies greatly affect the size of the APK. If configured, by editing the .csproj file, not to embed them the size of the APK is less than 10MB. BUT that doesn't mean anything since it is unsuitable for deployment.
To summarize, Xamarin.Forms saves the developer quite a few keystrokes but comes with the unbearable price of too big APKs.
21MB for two nearly empty Views plus an icon and a 11KB image just does not worth it.
Shame.
To close this conversation in a meaningful way and be fair to Xamarin.Forms I would like to say that I am happy with the APK size produced by Visual Studio 2017 (Community).
The signed package is 6MB, which is acceptable.
Good to see you are getting there!!
There is still more you can do though. SDK and UserAssemblies will improve the size further, by linking out unused .net code, just like R8 does for java code. You should also try Aot and EnableProfiledAot for faster start-up. Get rid of createpackaageperabi you don't need that when using aab's use instead which handles both apks and aabs. I'd suggest going through all the different settings taking note of each change. If it is an Android-only app then why not get rid of Forms and Xamarin.Essentials. Do cold start-up tests and look for Displayed in the log files to get the startup time as suggested in the link in my earlier post.
The easiest way to do all this without messing with your own project is to start with say the standard Tab or Nav app templates(strip out Xamarin.Essentials) and then fine-tune from there, correcting errors re proguard/r8 etc as you go. You'll hit a couple of proguard errors immediately. Just look in the logs to find whatever class is missing and add a keep to proguard.cfg.
Add the following to proguard.cfg to see what r8 is doing.
-printconfiguration config_yourappname.txt
-printseeds seeds.txt
-printusage usage.txt
Study the MS docs on the Build Process where all the different properties are explained.
When you get to looking at aabs check out Android Studio's APKAnalyser to see what effects the size of your apks and what is actually in them.
When you're happy with that, then convert all the support library stuff to Xamain.AndroidX. At that point, you'll be ready for Android 10. Well, that's my theory anyway...
Answers
Tutorial about Shrinking Android App Size you can refer to
https://devblogs.microsoft.com/xamarin/shrinking-android-app-size/
https://montemagno.com/how-to-keep-your-android-app-size-down/
https://xamarinhelp.com/reducing-app-file-size-xamarin-forms/
I've originally followed the official steps to build the app for release (Xamarin.Android > Deployment and Testing > Preparing an Application for Release) which includes linking and splitting the APKs and most of the tips mentioned in the links you've provided.
It looks like there's really nothing else to try so let me give the whole process another try and get back to you.
@Jarvan Nope. Nothing.
Thanks for the links but they provide no real solution.
An empty Xamarin.Forms project results in a 20+ MB APK with Sdk linking and code shrinking enabled.
As far as I can tell, the embedded assemblies greatly affect the size of the APK. If configured, by editing the .csproj file, not to embed them the size of the APK is less than 10MB. BUT that doesn't mean anything since it is unsuitable for deployment.
To summarize, Xamarin.Forms saves the developer quite a few keystrokes but comes with the unbearable price of too big APKs.
21MB for two nearly empty Views plus an icon and a 11KB image just does not worth it.
Shame.
For completeness, here are the Visual Studio 2019 Professional Android options:
Interestingly, Visual Studio 2017 Community produces a 12MB APK for the exact same project using Xamarin.Forms 3.4.0.1008975, Xam.Plugin.Connectivity 3.2.0 and the following Android options:
To close this conversation in a meaningful way and be fair to Xamarin.Forms I would like to say that I am happy with the APK size produced by Visual Studio 2017 (Community).
The signed package is 6MB, which is acceptable.
If size matter you must check your Xamarin version.
The latest version has a bug the increase the app size
https://github.com/xamarin/xamarin-android/issues/3454
Why don't you rerun your tests using the Visual Studio 2019 Preview? The bug referred to in the above post is already fixed in Xamarin.Android 10.0.0.43. Actually it was fixed in 10.0.0.40 if I remember correctly. Also to take maximum advantage of the Linker you should be using SDK and User Assemblies. There is plenty more you can do for both speed and size - refer to links in the following link https://devblogs.microsoft.com/xamarin/challenge-xamarin-android/
I would not have used a preview version for release version of my app.
https://docs.microsoft.com/en-us/xamarin/android/release-notes/10/10.0
This release is not "go-live" and not intended for use on production computers or for creating production code.
It is a lot bugs in Xamarin and you can not be sure that a preview version would work.
Currently you have to use a old version of Xamarin if size matters!
I believe this has just changed as the update to version 16.3 of Visual Studio just came in.
I updated Visual Studio 2019 Pro to version 16.3.0 (Xamarin.Android SDK 10.0.0.43) and tried your suggestions about smaller APK size with an empty Xamarin.Forms project. The results are not good.
I am not sure if there's value in sharing the details but the bottom line is the APK size is always bigger than the one generated with Visual Studio 2017 Community.
Generating the App Bundle was not successful either. Running
msbuild
from the command line gives me "access denied" error. I am happy other people could do it but I am just confused at the moment.FWIW, in Visual Studio 2017, the following Xamarin version is installed:
Xamarin 4.12.3.83 ([email protected])
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.
Xamarin Designer 4.16.30 (e0af99a34)
Visual Studio extension to enable Xamarin Designer tools in Visual Studio.
Xamarin Templates 1.1.128 (6f5ebb2)
Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.
Xamarin.Android SDK 9.1.7.0 (HEAD/ba9da7a76)
Xamarin.Android Reference Assemblies and MSBuild support.
Xamarin.iOS and Xamarin.Mac SDK 12.4.0.64 (9c8d8e0)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.
@Mimisss said - I am not sure if there's value in sharing the details but the bottom line is the APK size is always bigger than the one generated with Visual Studio 2017 Community.
Well without sharing the details, it is difficult to comment. Just the latest configuration of your release build is all that is needed. For both size and bundle recommendations
@GrahamMcKechnie As soon as I put things straight my test results started looking better; The difference in APK size between Xamarin.Android 9.1.7.0 and 10.0.0.43 is negligible. I've also tested with AAB. In details:
Xamarin.Android 9.1.7.0
Microsoft Visual Studio Community 2017
Version 15.9.16
VisualStudio.15.Release/15.9.16+28307.858
Microsoft .NET Framework
Version 4.8.03752
Installed Version: Community
Mono Debugging for Visual Studio 4.13.12-pre (9bc9548)
Xamarin 4.12.3.83 ([email protected])
Xamarin Designer 4.16.30 (e0af99a34)
Xamarin Templates 1.1.128 (6f5ebb2)
Xamarin.Android SDK 9.1.7.0 (HEAD/ba9da7a76)
Xamarin.iOS and Xamarin.Mac SDK 12.4.0.64 (9c8d8e0)
.NET Standard Project Dependencies
Xaramin.Essentials 1.0.1
Xamarin.Forms 3.4.0.1008975
NETStandard.Library 2.0.3
Android .csproj
Produced APKs
armeabi-v7a.apk
APK size: 12.3MB
Download size: 6.1MB
arm64-v8a.apk
APK size: 12.2MB
Download size: 6MB
Xamarin.Android 10.0.0.43
Microsoft Visual Studio Professional 2019
Version 16.3.0
VisualStudio.16.Release/16.3.0+29318.209
Microsoft .NET Framework
Version 4.8.03752
Installed Version: Professional
Mono Debugging for Visual Studio 16.3.7 (9d260c5)
Xamarin 16.3.0.274 ([email protected])
Xamarin Designer 16.3.0.230 (remotes/origin/[email protected])
Xamarin Templates 16.3.565 (27e9746)
Xamarin.Android SDK 10.0.0.43 (d16-3/8af1ca8)
Xamarin.Android Reference Assemblies and MSBuild support.
Mono: mono/mono/[email protected]
Java.Interop: xamarin/java.interop/[email protected]
LibZipSharp: grendello/LibZipSharp/[email protected]
LibZip: nih-at/libzip/rel-1-5-1[email protected]
ProGuard: xamarin/proguard/[email protected]
SQLite: xamarin/sqlite/[email protected]
Xamarin.Android Tools: xamarin/xamarin-android-tools/[email protected]
Xamarin.iOS and Xamarin.Mac SDK 13.2.0.42 (5e8a208)
.NET Standard Project Dependencies
Xaramin.Essentials 1.3.1
Xamarin.Forms 4.2.0.815419
NETStandard.Library 2.0.3
Android .csproj
Produced APKs
armeabi-v7a.apk
APK size: 13.7MB
Download size: 6.8MB
arm64-v8a.apk
APK size: 13.7MB
Download size: 6.7MB
Produced AAB
For AAB the apkanalyzer only reports one size:
Raw file size: 9.2MB
Good to see you are getting there!!
There is still more you can do though. SDK and UserAssemblies will improve the size further, by linking out unused .net code, just like R8 does for java code. You should also try Aot and EnableProfiledAot for faster start-up. Get rid of createpackaageperabi you don't need that when using aab's use instead which handles both apks and aabs. I'd suggest going through all the different settings taking note of each change. If it is an Android-only app then why not get rid of Forms and Xamarin.Essentials. Do cold start-up tests and look for Displayed in the log files to get the startup time as suggested in the link in my earlier post.
The easiest way to do all this without messing with your own project is to start with say the standard Tab or Nav app templates(strip out Xamarin.Essentials) and then fine-tune from there, correcting errors re proguard/r8 etc as you go. You'll hit a couple of proguard errors immediately. Just look in the logs to find whatever class is missing and add a keep to proguard.cfg.
Add the following to proguard.cfg to see what r8 is doing.
-printconfiguration config_yourappname.txt
-printseeds seeds.txt
-printusage usage.txt
Study the MS docs on the Build Process where all the different properties are explained.
When you get to looking at aabs check out Android Studio's APKAnalyser to see what effects the size of your apks and what is actually in them.
When you're happy with that, then convert all the support library stuff to Xamain.AndroidX. At that point, you'll be ready for Android 10. Well, that's my theory anyway...
use instead above - should have been
<AndroidSupportedAbis>armeabi-v7a;arm64-v8a</AndroidSupportedAbis>
. I forgot to mark it as code.Regretting converting my project to VS2019. The size of the app increased from 18MB to 150MB (after code shrinkage and everything).
That's huge!
I've recently started a new Xamarin Forms project (Xamarin 16.5.000.521) and the size of the debug APK is 8.5MB. The project is far from release so I cannot comment on the final size but things seem to have improved at least for new projects with VS2019.
Looks like the bundle package format is the way to go. While the release APK is 18MB choosing the bundle format reduces it to 10MB without any fancy options tweaking. I let linking to the default option (Sdk assemblies only) and selected ProGuard.
FWIW, ProGuard led to some classes being missed out from the bundle. No big deal, though. Even without it, the production AAB size is a little bigger than 10MB and the actual download is about 7MB, which is just great. This is the end of the discussion in this thread, I guess.