Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin - apk App Size

So, after all the hard-work developing the app using Xamarin.Forms, when I tried to create a release build today, I was shocked to see the app size is ~25MB - ~31MB (after SDK Only Linking, ProGuard, Creating apk for each abi). My resource folder is only in KBs. The apk actually was just 5MB in debug mode and was so happy to see it. I later realized that this is because of the option "Use Shared Runtime" which we are not supposed to use in Release Mode.

I then tried creating a blank Xamarin.Android app, but the release build with Linking SDK & User Assemblies, ProGuard, APK for each abi is still ~8MB to ~13MB.

Per the below link the minimum size is 2.9MB with the Hello World app, however I am unable to create such size. https://developer.xamarin.com/guides/android/advanced_topics/application_package_sizes/

For my app and the blank app I created, the necessary dlls seem to be high (example mscorlib.dll is 2.2mb etc, where as the link says after linking it will become 1 mb) Here is what I see as my assembly folder after extracting the apk enter image description here

In one of the recent Microsoft tech conferences I happened to know that "9 News" app (link below) was built using xamarin, and the creators were present on the stage. However I was surprised with it's app size. It is only 5.85 MB. I am unsure how that is achieved?

Can any one help me with these?

https://play.google.com/store/apps/details?id=nineNewsAlerts.nine.com

I am also curious to know if Microsoft doing something to improve app package sizes? Or will this be resolved if they bring .NET core to xamarin?

like image 784
My Helper Avatar asked Mar 31 '17 02:03

My Helper


People also ask

What is the APK size?

Each time you upload an APK using the Google Play Console, you have the option to add one or two expansion files to the APK. Each file can be up to 2GB and it can be any format you choose, but we recommend you use a compressed file to conserve bandwidth during the download.

What is the max size of APK?

Each expansion file can be up to 2GB in size. Users must run Play Store version 5.2 or higher to install 100MB APKs.

Is Xamarin good for apps?

Since its appearance in 2011, Xamarin has become a great option for cross-platform app development, a faster way to build iOS, Android, and Windows apps.


2 Answers

Xamarin Android APK files have a larger size than usual because they include the Xamarin libraries, that translate C# code to Java code, to run in Android OS.

Using the following options, you can reduce the APK size:

  • Configuration: Active (Release).
  • Platform: Active (Any CPU). These are necessary to build your APK for the Google Play Store.
  • Use Shared Runtime: false. If you set it to true, the APK will use Mono Runtime to execute. The Mono Runtime is installed automatically when debugging through USB, but not in the Release APK. If Mono Runtime is not installed in the device and this option is set to true in the Release APK, the app will crash.
  • Generate one package (.apk) per selected ABI: false. Create your APK for as many platforms as possible, for compatibility reasons.
  • Enable Multi-Dex: true, but you can set it to false if your app is not very complex (that is, has less than 65536 variables or methods, see here).
  • Enable developer instrumentation (debugging and profiling): false for Release APK.
  • Linking: SDK and User Assemblies. This will make the Xamarin compiler to remove all unused classes from SDK and your code, reducing the APK size.
  • Supported architectures: Select all, for compatibility reasons.

Here is a print screen example:

enter image description here

like image 106
Alexandre Avatar answered Oct 09 '22 06:10

Alexandre


Here's the stats of my Xamarin.Forms app size from Google Play Console. You can see how much it went down as soon as I took the subject seriously and moved away from default Xamarin settings:

enter image description here

In addition to the measures that are typically found when googling the subject (linking, keeping eye on own resources, APK per ABI etc.) here're a few of my own findings and quirks:

  • Enabling Managed TLS Provider shoves of ~1MB - by default you have 'Native TLS 1.2' option selected in Project Options -> Android Options -> Advanced button -> SSL/TLS implementation drop down. Managed TLS is version 1.1 only, might be an issue from someone
  • Upgrade to Xamarin.Forms 4.1 gives ~1MB reduction (comparing to 3.x and 4.0) - they removed some of unused yet referenced Android Compatability Libraries
  • Enabling aapt2 packager gives ~1MB reduction for App Compat libs resources only (those referenced and included by Xamarin.Forms). Might give more if you have many of your own resources. You can have aapt2 further striping down resources by using the following extra args in you Android's .csproj file:

    <PropertyGroup>
       <AndroidUseAapt2>true</AndroidUseAapt2>
       <AndroidAapt2LinkExtraArgs>--no-version-vectors -c en-rUS</AndroidAapt2LinkExtraArgs>
    </PropertyGroup>
    
  • Turning on D8 and R8 gives another ~1MB for a small Xamarin.Forms app (Project Options -> Android Options or .csproj)

    <PropertyGroup>
        <AndroidDexTool>d8</AndroidDexTool>
        <AndroidLinkTool>r8</AndroidLinkTool>
    </PropertyGroup>
    
  • SkiaSharp 1.60.3 gives ~2MB economy per architecture, compared to more recent versions (e.g. 1.68.0). It's worthwhile looking out for dependencies and their versions bloating your APK.

  • Disabling AoT (if you had it previously enabled, it's off by default) can easily cut your app size in half. Turning on Ahead-of-Time complication could have been a deliberate step to improve your app's start-up performance. There's a clear trade-off, either you go with AoT and have huge app size OR you don't have it and keep size minimal with slow app launches. One of the points to consider when deciding on the trade-off... Most ASO articles (as well as Google Play Console) mention how important it is to have app size small to increase installs conversion. Clearly when browsing Google Play it's app download size that is displayed, not app start time.

  • Adjusting AoT to minimize it's footprint, add the following in .csproj for your Release configuration:

    <PropertyGroup>
        <AotAssemblies>true</AotAssemblies>
        <AndroidAotAdditionalArguments>no-write-symbols,nodebug</AndroidAotAdditionalArguments>
    </PropertyGroup>
    
  • Doing Partial AoT. By default AoT goes through all assemblies resolved by the project and adds 30+ .so files in the /lib directory of your APK. There're numerous app compat libs, BCL and system libs. One might want to have control over which assemblies to put through AoT and which ones to ignore in order find a sweet spot between performance and app size. Well, there's no such thing available as standard feature (at least I didn't find one). You can play with Xamarin build process by making changes to Xamarin.Android.Common.targets - you can find some insights into this process here. I found my golden mean by AoT'ing only three libs (1 my own XF shared UI lib and 2 XF libs):

    <_ResolvedUserAssemblies2 Include="Tmp/android/assets/Xamarin.Forms.Core.dll;Tmp/android/assets/Saplin.CPDT.UICore.dll;Tmp/android/assets/Xamarin.Forms.Platform.Android.dll;" />

P.S.: Enabling Linking (SDK and User Assemblies)- 90% chance that you'll find your app broken, if you extensively use XAML and bindings. Add your own libs to linker exceptions - XF class library that hosts your UI, any class libs you created and that might use reflection.

P.P.S: with my minification efforts, partial AoT and paying with async/deffered Xamarin.Forms UI loading (here and here) I reached a significant app size reduction (see pic. above) with significant app launch time improvements (measured on Nokia N1 through ADB):

  • No AOT, sync UI (ms): 3613, 3586, 3576
  • Partial AOT, async UI (ms): 2202, 2255, 2258
like image 26
Maxim Saplin Avatar answered Oct 09 '22 07:10

Maxim Saplin