-
Notifications
You must be signed in to change notification settings - Fork 534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for Dynamic Feature Modules #4810
Comments
@fruitedev I remember there might have been some limitations when I first implemented app bundles: I remember something about needing to support "Instant Apps" for dynamic modules to work, which has a hard file-size limit. The Mono runtime was over the limit. We should still look into this again. Anyone interested, please give a thumbs up above and that will help us know the demand, thanks! |
@jonathanpeppers Let's consider that the module I want to load dynamically is an aar archive with some jar dependencies and I have a binding over this one. Would that make the process easier on your side ? I mean I do want to load this aar dynamically since it's pretty heavy. |
Now that Apple has introduced App Clips, clients are now more interested in Android Instant Apps. Using app bundles may not be so possible due to the Mono runtime limit and that is fine, but if there was a way we could at least attach natively written instant app apk's as feature modules to the Xamarin.Android app that would be great. |
Still really really interested in the dynamic delivery for our applications. We are open for a quick call to explain more about why if you want. |
I found that a community member has already bound the PlayCore library, https://github.com/PatGet/XamarinPlayCoreUpdater. This might have enough support to allow you to deliver a natively written apk as a dynamic feature and keep the main app as a Xamarin App. |
@dellis1972 Hum that might be but actually "publishing" this module to the play store will maybe be tricky if even possible as the application is in Xamarin. Even by creating a native application just for packaging this module I think it will not work well. |
@johnthiriet I haven't heard of anyone doing it yet. The developer it seems only used it for in app updates. |
…ets. Context dotnet#4810 When using app bundles users install the application from an `apkset`. At this time this only contains the base application. However we might in the future support dynamic features in some fashion. In this case developers should be able to pick which features they want installed. This commit adds an `AndroidInstallModules` ItemGroup which will allow developers to specify which modules to install. By default it will be empty. This means all modules which are to be installed on first install will be installed. So there is no change in the current behavior. This commit also adds support for passing additional arguments to `bundletool` via the new `$(AndroidBundleToolExtraArgs)` property.
I did some investigation last week as to what might be needed to support this feature. The next issue is how do we build a "feature". Some investigation into this shows that it is not going to be straight forward. The reason we need to build the features after is the
This is required because the entires in the AndroidManifest.xml we need to include in the "Feature" MUST use resources from the main app for its distribution elements. This is a sample of a working AndoridManfiest.xml for an "Asset Feature"
Note the
We then need to manipulate the output file to move things around a bit. By default Once we have this "feature" zip file build we can then pass that to the The current idea on how an end user might use this is that we allow for an additional piece of meta data on the
In this case At runtime once a user has installed a "feature" they can then use
For assemblies we need to decide what to do. For java apps they can call The other option is to use So we have a number of things we need to implement and investigate before we can fully support this. We will probably have to break this up into a smaller set of projects. The initial goal will be to support dynamic delivery of "assets" the follow that up with dynamic delivery of assemblies later since the runtime changes will not be easy. UPDATE: So more investigation has turned up some interesting info. Each "Feature" needs to have a different package-id. By Some thoughts on using
This will allow us to pass in not only the main app dll but also all the references which the main app have. This will include things like So a new todo items are.
This is just a brain dump of all the stuff I have found other the last couple of days. There are probably more things we need to do but this is a good starting point. To manage some expectations, this is not going to be a quick process. We have not even mentioned IDE integration or the actual end user experience yet. So this is going to be an on going process. But we are looking at it, which is a start :) |
Ah, so we should be able to knock this out in an afternoon, right??? 👀 |
@dellis1972 That is the most interesting thing I have read in weeks :-) |
…ets. Context dotnet#4810 When using app bundles users install the application from an `apkset`. At this time this only contains the base application. However we might in the future support dynamic features in some fashion. In this case developers should be able to pick which features they want installed. This commit adds an `AndroidInstallModules` ItemGroup which will allow developers to specify which modules to install. By default it will be empty. This means all modules which are to be installed on first install will be installed. So there is no change in the current behavior. This commit also adds support for passing additional arguments to `bundletool` via the new `$(AndroidBundleToolExtraArgs)` property.
…ets. Context dotnet#4810 When using app bundles users install the application from an `apkset`. At this time this only contains the base application. However we might in the future support dynamic features in some fashion. In this case developers should be able to pick which features they want installed. This commit adds an `AndroidInstallModules` ItemGroup which will allow developers to specify which modules to install. By default it will be empty. This means all modules which are to be installed on first install will be installed. So there is no change in the current behavior. This commit also adds support for passing additional arguments to `bundletool` via the new `$(AndroidBundleToolExtraArgs)` property.
…ets. Context dotnet#4810 When using app bundles users install the application from an `apkset`. At this time this only contains the base application. However we might in the future support dynamic features in some fashion. In this case developers should be able to pick which features they want installed. This commit adds an `AndroidInstallModules` ItemGroup which will allow developers to specify which modules to install. By default it will be empty. This means all modules which are to be installed on first install will be installed. So there is no change in the current behavior. This commit also adds support for passing additional arguments to `bundletool` via the new `$(AndroidBundleToolExtraArgs)` property.
…ets. Context dotnet#4810 When using app bundles users install the application from an `apkset`. At this time this only contains the base application. However we might in the future support dynamic features in some fashion. In this case developers should be able to pick which features they want installed. This commit adds an `AndroidInstallModules` ItemGroup which will allow developers to specify which modules to install. By default it will be empty. This means all modules which are to be installed on first install will be installed. So there is no change in the current behavior. This commit also adds support for passing additional arguments to `bundletool` via the new `$(AndroidBundleToolExtraArgs)` property.
…ets. Context dotnet#4810 When using app bundles users install the application from an `apkset`. At this time this only contains the base application. However we might in the future support dynamic features in some fashion. In this case developers should be able to pick which features they want installed. This commit adds an `AndroidInstallModules` ItemGroup which will allow developers to specify which modules to install. By default it will be empty. This means all modules which are to be installed on first install will be installed. So there is no change in the current behavior. This commit also adds support for passing additional arguments to `bundletool` via the new `$(AndroidBundleToolExtraArgs)` property.
…ets. Context dotnet#4810 When using app bundles users install the application from an `apkset`. At this time this only contains the base application. However we might in the future support dynamic features in some fashion. In this case developers should be able to pick which features they want installed. This commit adds an `AndroidInstallModules` ItemGroup which will allow developers to specify which modules to install. By default it will be empty. This means all modules which are to be installed on first install will be installed. So there is no change in the current behavior. This commit also adds support for passing additional arguments to `bundletool` via the new `$(AndroidBundleToolExtraArgs)` property.
…ets. Context dotnet#4810 When using app bundles users install the application from an `apkset`. At this time this only contains the base application. However we might in the future support dynamic features in some fashion. In this case developers should be able to pick which features they want installed. This commit adds an `AndroidInstallModules` ItemGroup which will allow developers to specify which modules to install. By default it will be empty. This means all modules which are to be installed on first install will be installed. So there is no change in the current behavior. This commit also adds support for passing additional arguments to `bundletool` via the new `$(AndroidBundleToolExtraArgs)` property.
…ets. Context dotnet#4810 When using app bundles users install the application from an `apkset`. At this time this only contains the base application. However we might in the future support dynamic features in some fashion. In this case developers should be able to pick which features they want installed. This commit adds an `AndroidInstallModules` ItemGroup which will allow developers to specify which modules to install. By default it will be empty. This means all modules which are to be installed on first install will be installed. So there is no change in the current behavior. This commit also adds support for passing additional arguments to `bundletool` via the new `$(AndroidBundleToolExtraArgs)` property.
…ets. Context dotnet#4810 When using app bundles users install the application from an `apkset`. At this time this only contains the base application. However we might in the future support dynamic features in some fashion. In this case developers should be able to pick which features they want installed. This commit adds an `AndroidInstallModules` ItemGroup which will allow developers to specify which modules to install. By default it will be empty. This means all modules which are to be installed on first install will be installed. So there is no change in the current behavior. This commit also adds support for passing additional arguments to `bundletool` via the new `$(AndroidBundleToolExtraArgs)` property.
…5327) Context: #4810 Context: #4810 (comment) Context: https://developer.android.com/guide/app-bundle/play-feature-delivery Android introduced support for using [Android App Bundles][0] to package features into separately downloadable [feature modules][1]. When using app bundles, users install the application from an `apkset`. At this time this only contains the base application. However we might in the future support feature modules in some fashion. In this case developers should be able to pick which features they want installed. This commit adds an `@(AndroidInstallModules)` ItemGroup which will allow developers to specify which modules to install. By default it will be empty, which means that all modules which are to be installed on first install will be installed. There will be no change to current behavior when `@(AndroidInstallModules)` is empty. Also add support for passing additional arguments to `bundletool` via the new `$(AndroidBundleToolExtraArgs)` property. [0]: https://developer.android.com/guide/app-bundle [1]: https://developer.android.com/guide/app-bundle/play-feature-delivery
Hi @dellis1972 and all |
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
I'm working on the initial support for this on #5890 . It would be nice to get some community feedback on how I plan to implement this. You can read the PR and some initial documentation. All of this is subject to change, but it's a good start. I have something working for |
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Looking forward to this feature, happy to know that a Monogame veteran is doing the job ;) may i help you testing it? |
@Eversor its still a work in progress I'm afraid. I have had to put it on hold for a while because of other more important tasks on Xamarin.Android. That said I did find some time to put a MonoGame specific example together at https://github.com/infinitespace-studios/MonoGameAndroidAssetPackExample for those who are interested 😄 |
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
Context dotnet#4810 This is the first implementation for supporting building Dynamic Feature Assets modules for Android. This idea is to have these "features" as standard Xamarin Android Library projects. The `ProjectReference` will need to use the following ```xml <ItemGroup> <ProjectReference Include="Features\AssetsFeature\AssetsFeature.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <AndroidDynamicFeature>true</AndroidDynamicFeature> </ProjectReference> </ItemGroup> ``` We set `ReferenceOutputAssembly` to `false` to ensure that the assembly for the feature is NOT included in the final aab file. The new meta Data `AndroidDynamicFeature` allows the build system to pick up project references which are "features". As part of the final packaging step of the main app we will gather up all the `ProjectRefernce` items which have `AndroidDynamicFeature` set to `true` (and maybe `ReferenceOutputAssembly` set to `false`). This will be done by the `_BuildDynamicFeatures` which will run just after `_CreateBaseApk`. It will call `_GetDynamicFeatureOutputs` for each `ProjectReference` which will collect the `output` files for each feature. It will then call the `BuildDynamicFeature` target via the `MSBuild` task for each `ProjectReference`. The `BuildDynamicFeature` is the target responsible for collecting all the assets and packaging them using `aapt2` up into a zip. Once all the `BuildDynamicFeature` calls are complete the created `zip` files will be added to the `AndroidAppBundleModules` and then included in the final `aab` file. It might seem odd that the feature projects are built after the main app. However this is required because the feature needs to use the `packaged_resources` file as an input to `aapt2` when building the feature. This is why the `_BuildDynamicFeatures` happens AFTER `_CreateBaseApk`. It is only at that point that the final `packaged_resources` file exists. One of the very weird things is that the feature zip needs to be built using the `aapt2` `--static-lib` flag. As a result we need to call `aapt2 convert` on the final zip. This is because it is in the `apk` `binary` format and needs to be converted over to the `aab` `proto` format. So there is a new `Aapt2Convert` task which handles that job. It also makes sure the `AndroidManifest.xml` file is in the right place when converting to `proto` format. A basic project example using .net 6 for a feature would look like this. ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0-android</TargetFramework> </PropertyGroup> </Project> ``` As you can see it is just a normal library project. At this time is CANNOT contain any `AndroidResource` items such as drawables or layouts. It must only contain `AndroidAsset` items. So we probably should have a new template for a `Dynamic Feature` which just creates the `csproj` and the `Assets` folder. One sticking point is probably the `AndroidManifest.xml` file which we need for a `feature`. There is a sample ```xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:dist="http://schemas.android.com/apk/distribution" android:versionCode="1" android:versionName="1.0" package="com.companyname.DynamicAssetsExample" featureSplit="assetsfeature" android:isFeatureSplit="true"> <dist:module dist:title="@string/assetsfeature" dist:instant="false"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <application android:hasCode="false" tools:replace="android:hasCode" /> </manifest> ``` The interesting parts are all the additional `dist` elements. What we can probably do is auto generate this during the `BuildDynamicFeature`. However we need to think carefully about this since if we plan to have code and `Activities` in the feature at some point, those will also need to end up in the `AndroidManifest.xml`. For additional information on the Play Core Dynamic Features check the following links. [1] https://developer.android.com/guide/playcore/asset-delivery [2] https://developer.android.com/guide/playcore/feature-delivery
For those of you who are interested in asset packs I have a new PR up at #8631. We could use some feedback on the approach we plan to take on this if anyone has the time :) |
Context: #4810 Google Android began supporting splitting up the app package into multiple "packs" with the introduction of the `aab` package format. Each "pack" can be downloaded to the device either at install time or on-demand. This allows application developers to save space and install time by only installing the required parts of the app initially, then installing other packs as required. There are two types of packs: Feature packs and Asset packs. *Feature* pack contains *non-native* Java code and other resources. Java code in feature packs can be launched via `Context.StartActivity()`. Currently, .NET Android cannot support Feature packs, as Feature packs cannot contain native code. *Asset* packs contain *only* `@(AndroidAsset)`s. They *cannot* contain any code or other resources. This type of pack can be installed at install-time, fast-follow, or ondemand. It is most useful for apps which contain a lot of Assets, such as Games or Multi Media applications. Consider a default Android app with an asset: % dotnet new android % mkdir Assets % touch Assets/movie1.mp4 % dotnet build -c Release % unzip -l bin/Release/net9.0-android/*-Signed.aab | grep -Ei 'asset|movie' 0 01-01-2010 00:00 base/assets/movie1.mp4 … 12 01-01-2010 00:00 base/assets.pb Note that assets are listed within the `.aab`, within the `base/assets` directory. Add support for the following metadata items: * `%(AndroidAsset.AssetPack)`: the *name* of the asset pack that should contain the asset. * `%(AndroidAsset.DeliveryType)`: How the named asset pack should be installed. When `%(AndroidAsset.AssetPack)` is specified, the asset is placed into a different directory within the `.aab` file. For example, add additional assets: % touch Assets/movie-install.mp4 % touch Assets/movie-follow.mp4 % touch Assets/movie-demand.mp4 Then update the `.csproj` to specify `%(AssetPack)` and `%(DeliveryType)`: <ItemGroup> <AndroidAsset Update="Assets\movie-install.mp4" AssetPack="install_movies" DeliveryType="InstallTime" /> <AndroidAsset Update="Assets\movie-follow.mp4" AssetPack="follow_movies" DeliveryType="FastFollow" /> <AndroidAsset Update="Assets\movie-demand.mp4" AssetPack="demand_movies" DeliveryType="OnDemand" /> </ItemGroup> Now we see: % dotnet build -c Release % unzip -l bin/Release/net9.0-android/*-Signed.aab | grep -Ei 'asset|movie' 0 01-01-2010 00:00 base/assets/movie1.mp4 12 01-01-2010 00:00 base/assets.pb 0 01-01-2010 00:00 demand_movies/assets/movie-demand.mp4 644 01-01-2010 00:00 demand_movies/manifest/AndroidManifest.xml 12 01-01-2010 00:00 demand_movies/assets.pb 0 01-01-2010 00:00 follow_movies/assets/movie-follow.mp4 646 01-01-2010 00:00 follow_movies/manifest/AndroidManifest.xml 12 01-01-2010 00:00 follow_movies/assets.pb 0 01-01-2010 00:00 install_movies/assets/movie-install.mp4 648 01-01-2010 00:00 install_movies/manifest/AndroidManifest.xml 12 01-01-2010 00:00 install_movies/assets.pb The `AndroidManifest.xml` files tell the Google Play Store how they asset packs should be deployed.
Asset Pack support has been merged, should be in the next .NET 9 Previous. Still trying to figure out how we can even support feature packs :/ |
Hello,
I know there is support for AppBundles which makes things easier, but i couldn't find whether Dynamic Feature Modules is supported or not. Support of Dynamic Feature Modules will be really really helpful for us so please share any plan you have.
Thanks,
The text was updated successfully, but these errors were encountered: