An Example of using Dynamic Asset Delivery with Xamarin Android.
The solution is made up of 2 projects.
- InstallTimeExample. This is the main Maui application for the InstallTime Example.
- AssetsFeature. This is the project for the Asset only dynamic feature.
There is a global.json
file which pulls in the Microsoft.Build.NoTargets
SDK
which we use for the "Feature" projects. This is so they do not produce an assembly.
The way the build works is we have a custom set of targets in the Targets\DynamicFeature.targets
file. The four targets are BuildAssetFeature
,IncludeAssetFeature
, IncludeAssets
and PackageAssets
. The first two targets are build as part of the main Maui application. It is responsible for
finding "Feature" projects and then calling the PackageAssets
or IncludeAssets
target on each of them. Which target that gets called depends on the TargetFramework
. For
net7.0-android
based apps BuildAssetFeature
and PackageAssets
are called. For
other platforms IncludeAssetFeature
and IncludeAssets
are called. This is because
of the different restrictions on each platform.
It does this by looking for ProjectReferences
which have the DynamicFeature
metadata
set to true
.
<ProjectReference Include="..\AssetsFeature\AssetsFeature.csproj">
<Project>{EABACE4D-E999-48FA-B417-ECD29C8AB6E5}</Project>
<Name>AssetsFeature</Name>
<!-- These next two items are REALLY IMPORTANT!!!! -->
<DynamicFeature>true</DynamicFeature>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
NOTE: Feature references should ALSO have the ReferenceOutputAssembly
set to false. This
stops the .net packaging system from referencing the "fake" assembly which might be produced
in the feature project.
The PackageAssets
target will run for each "feature" project. It is responsible for
using aapt2
to package up the files in the Assets
folder (including subdirectories)
and generating a "Feature" package/zip file.
The outputs of PackageAssets
are then passed back to BuildAssetFeature
which then includes
those zip files in the @(AndroidAppBundleModules)
ItemGroup. These will then be included
in the final aab
file as dynamic features.
The IncludeAssets
target weill run for each "feature" project for platforms other than
android. This target will just add the files in the Assets
folder to the MauiAsset
ItemGroup. This allows the assets to be included in the final app.
To create a feature you need a few things. The first is a Microsoft.Build.NoTargets
project
which imports the Targets\DynamicFeatures.targets
file. See AssetFeature\AssetFeature.csproj
for an example.
Next you need an AndroidManifest.xml
file. This is where you define how they "Feature" will be
installed via the dist:module
and dist:delivery
elements.
IMPORTANT: The dist:type
MUST be set to asset-pack
!
The package
attribute on the manifest
element MUST match the value of the main application.
And finally the split
value is the name which the "Feature" will be called in the final package.
For non android platforms, all the assets will be included as normal MauiAsset
items.
Install time asset packs for android are installed along side your app during the installation
process. There is no additional work needed to download them.
For other platforms the files will be included in your app as with other MauiAssete
items.
Accessing these assets can be done via the normal OpenAppPackageFileAsync
method.
using Stream fileStream = await FileSystem.Current.OpenAppPackageFileAsync("Foo.txt");