-
Notifications
You must be signed in to change notification settings - Fork 526
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
spec & prototype of Android App Bundles #2841
Conversation
Shouldn't be there an Edit: |
I don't know, but our Java code is running: https://github.com/xamarin/xamarin-android/blob/f098d9c161a3d602c75f8e866bb22262bf25539e/src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.java#L23 Then our It crashed trying to load mono. There are some specifics with app bundles and |
9a434a8
to
2a4f7bc
Compare
Context: dotnet/android#2841 In my initial work to support Android App Bundles in Xamarin.Android, apps were crashing on startup with an error such as: monodroid: Using runtime path: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/lib/arm64 monodroid: Trying to load sgen from: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/lib/arm64/libmonosgen-64bit-2.0.so monodroid: Trying to load sgen from: /system/lib64/libmonosgen-2.0.so monodroid: Cannot find 'libmonosgen-2.0.so'. Looked in the following locations: monodroid: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/base.apk!/lib/arm64-v8a monodroid: Do you have a shared runtime build of your app with AndroidManifest.xml android:minSdkVersion < 10 while running on a 64-bit Android 5.0 target? This combination is not supported. monodroid: Please either set android:minSdkVersion >= 10 or use a build without the shared runtime (like default Release configuration). Android App Bundles use `android:extractNativeLibs="false"` also known as "embedded DSOs". The file system showed the app contents are in multiple APK files: $ run-as UnnamedProject.UnnamedProject ls -l /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/ total 22663 -rw-r--r-- 1 system system 2994137 2019-03-18 10:37 base.apk drwxr-xr-x 3 system system 3488 2019-03-18 10:37 lib -rw-r--r-- 1 system system 20161118 2019-03-18 10:37 split_config.arm64_v8a.apk -rw-r--r-- 1 system system 23203 2019-03-18 10:37 split_config.xxxhdpi.apk The paths to these APK files were missing in `LoadApplication`: https://github.com/xamarin/xamarin-android/blob/f098d9c161a3d602c75f8e866bb22262bf25539e/src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.java#L23 The only APK listed was: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/base.apk It appears we need to use a new API that became available in API 21: https://developer.android.com/reference/android/content/pm/ApplicationInfo.html#splitPublicSourceDirs After using the value from `ApplicationInfo.splitPublicSourceDirs`: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/split_config.arm64_v8a.apk /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/split_config.xxxhdpi.apk Xamarin.Android apps deployed as an Android App Bundle were able to startup properly after this change. My initial research is showing we probably can't use "Fast Deployment" in combination with Android App Bundles. So I don't think we should make any changes to `MonoRuntimeProvider.Shared.java`.
2a4f7bc
to
cfecf6e
Compare
Context: dotnet/android#2841 In my initial work to support Android App Bundles in Xamarin.Android, apps were crashing on startup with an error such as: monodroid: Using runtime path: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/lib/arm64 monodroid: Trying to load sgen from: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/lib/arm64/libmonosgen-64bit-2.0.so monodroid: Trying to load sgen from: /system/lib64/libmonosgen-2.0.so monodroid: Cannot find 'libmonosgen-2.0.so'. Looked in the following locations: monodroid: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/base.apk!/lib/arm64-v8a monodroid: Do you have a shared runtime build of your app with AndroidManifest.xml android:minSdkVersion < 10 while running on a 64-bit Android 5.0 target? This combination is not supported. monodroid: Please either set android:minSdkVersion >= 10 or use a build without the shared runtime (like default Release configuration). Android App Bundles use `android:extractNativeLibs="false"` also known as "embedded DSOs". The file system showed the app contents are in multiple APK files: $ run-as UnnamedProject.UnnamedProject ls -l /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/ total 22663 -rw-r--r-- 1 system system 2994137 2019-03-18 10:37 base.apk drwxr-xr-x 3 system system 3488 2019-03-18 10:37 lib -rw-r--r-- 1 system system 20161118 2019-03-18 10:37 split_config.arm64_v8a.apk -rw-r--r-- 1 system system 23203 2019-03-18 10:37 split_config.xxxhdpi.apk The paths to these APK files were missing in `LoadApplication`: https://github.com/xamarin/xamarin-android/blob/f098d9c161a3d602c75f8e866bb22262bf25539e/src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.java#L23 The only APK listed was: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/base.apk It appears we need to use a new API that became available in API 21: https://developer.android.com/reference/android/content/pm/ApplicationInfo.html#splitPublicSourceDirs After using the value from `ApplicationInfo.splitPublicSourceDirs`: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/split_config.arm64_v8a.apk /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/split_config.xxxhdpi.apk Xamarin.Android apps deployed as an Android App Bundle were able to startup properly after this change. My initial research is showing we probably can't use "Fast Deployment" in combination with Android App Bundles. So I don't think we should make any changes to `MonoRuntimeProvider.Shared.java`. Unfortunately if your `targetSdkVersion` is 20 or less, this code would not compile! So I included a source file with the original code: `MonoRuntimeProvider.Bundled.20.java`. We will need to make sure this file is used in xamarin-android for older `targetSdkVersion`: https://github.com/xamarin/xamarin-android/blob/5fed357fcfc7c59484fb1eb9b3748bc0545c8a25/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets#L1896-L1899
Context: dotnet/android#2841 In my initial work to support Android App Bundles in Xamarin.Android, apps were crashing on startup with an error such as: monodroid: Using runtime path: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/lib/arm64 monodroid: Trying to load sgen from: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/lib/arm64/libmonosgen-64bit-2.0.so monodroid: Trying to load sgen from: /system/lib64/libmonosgen-2.0.so monodroid: Cannot find 'libmonosgen-2.0.so'. Looked in the following locations: monodroid: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/base.apk!/lib/arm64-v8a monodroid: Do you have a shared runtime build of your app with AndroidManifest.xml android:minSdkVersion < 10 while running on a 64-bit Android 5.0 target? This combination is not supported. monodroid: Please either set android:minSdkVersion >= 10 or use a build without the shared runtime (like default Release configuration). Android App Bundles use `android:extractNativeLibs="false"` also known as "embedded DSOs". The file system showed the app contents are in multiple APK files: $ run-as UnnamedProject.UnnamedProject ls -l /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/ total 22663 -rw-r--r-- 1 system system 2994137 2019-03-18 10:37 base.apk drwxr-xr-x 3 system system 3488 2019-03-18 10:37 lib -rw-r--r-- 1 system system 20161118 2019-03-18 10:37 split_config.arm64_v8a.apk -rw-r--r-- 1 system system 23203 2019-03-18 10:37 split_config.xxxhdpi.apk The paths to these APK files were missing in `LoadApplication`: https://github.com/xamarin/xamarin-android/blob/f098d9c161a3d602c75f8e866bb22262bf25539e/src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.java#L23 The only APK listed was: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/base.apk It appears we need to use a new API that became available in API 21: https://developer.android.com/reference/android/content/pm/ApplicationInfo.html#splitPublicSourceDirs After using the value from `ApplicationInfo.splitPublicSourceDirs`: /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/split_config.arm64_v8a.apk /data/app/UnnamedProject.UnnamedProject-BcBcWREBNkF09eleaCTkuw==/split_config.xxxhdpi.apk Xamarin.Android apps deployed as an Android App Bundle were able to startup properly after this change. My initial research is showing we probably can't use "Fast Deployment" in combination with Android App Bundles. So I don't think we should make any changes to `MonoRuntimeProvider.Shared.java`. Unfortunately if your `targetSdkVersion` is 20 or less, this code would not compile! So I included a source file with the original code: `MonoRuntimeProvider.Bundled.20.java`. I added various tests changes to make sure things are working: * Added an `ExampleActivity` and `ExampleInstrumentation` to the `SupportDeclarations` for `JavaCallableWrapperGeneratorTests`. * Updated `TypeNameMapGeneratorTests` to use these types, too. * Added `GenerateActivity` and `GenerateInstrumentation` tests. The former tests API 28 vs API 20. ~~ Changes in xamarin-android ~~ We will need to make sure the `MonoRuntimeProvider.Bundled.20.java` file is used in xamarin-android for older `targetSdkVersion`: https://github.com/xamarin/xamarin-android/blob/5fed357fcfc7c59484fb1eb9b3748bc0545c8a25/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets#L1896-L1899 We also have this: https://github.com/xamarin/xamarin-android/blob/b08240ee50e941cb326688cc0dcf5969ebfe5473/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs#L246 These two places may be doing the same work twice, so we should fix that, too. We also need to pass in `TargetSdkVersion` here: https://github.com/xamarin/xamarin-android/blob/5fed357fcfc7c59484fb1eb9b3748bc0545c8a25/src/Xamarin.Android.Build.Tasks/Generator/Generator.cs#L26-L29
Context: dotnet/java-interop#422 Context: dotnet#2841 In an effort to consolidate our Java source code, there are a couple files that should be moved into xamarin-android: * `MonoRuntimeProvider.Bundled.java` * `MonoRuntimeProvider.Shared.java` This gives us more flexibility in Xamarin.Android to change these files, in cases such as: * Is the shared runtime used? * Is it a specific API level? * Could we call into some pre-compiled code instead? I moved the files, and left them as-is. The only other changes are due to `Java.Interop.Tools.JavaCallableWrappers.csproj` no longer containing resources: * The `<CopyResource/>` MSBuild task can just look in the executing assembly. * The`<GenerateJavaStubs/>` MSBuild task can just look in the executing assembly.
Context: dotnet/java-interop#422 Context: dotnet#2841 Bump to xamarin/java.interop/master@7c7eae3a Changes: dotnet/java-interop@f84c236...7c7eae3 In an effort to consolidate our Java source code, there are a couple files that should be moved into xamarin-android: * `MonoRuntimeProvider.Bundled.java` * `MonoRuntimeProvider.Shared.java` This gives us more flexibility in Xamarin.Android to change these files, in cases such as: * Is the shared runtime used? * Is it a specific API level? * Could we call into some pre-compiled code instead? I moved the files, and left them as-is. The only other changes are due to `Java.Interop.Tools.JavaCallableWrappers.csproj` no longer containing resources: * The `<CopyResource/>` MSBuild task can just look in the executing assembly. * The`<GenerateJavaStubs/>` MSBuild task can just look in the executing assembly.
Context: dotnet/java-interop@7c7eae3 Context: #2841 `make prepare` creates `MonoInfo.props`. Add `Xamarin.Android.Tools.Bytecode.ClassPath.Load(Stream,bool)`. Support API-Q Java stub constructs in xamarin-android-docimporter-ng. Upgrades to NUnit 3.11.0 and NUnit.ConsoleRunner 3.9.0 Reworks `MonoRuntimeProvider.*.java` usage in `JavaCallableWrapperGenerator`. In an effort to consolidate our Java source code, there are a couple files that we're moving into xamarin-android: * `MonoRuntimeProvider.Bundled.java` * `MonoRuntimeProvider.Shared.java` This gives us more flexibility in Xamarin.Android to change these files, in cases such as: * Is the shared runtime used? * Is it a specific API level? * Could we call into some pre-compiled code instead? Instead of `JavaCallableWrapperGenerator` containing the `MonoRuntimeProvider.*.java` files as a resource, it will instead use a new `JavaCallableWrapperGenerator.MonoRuntimeInitialization` property, which must be set by `<GenerateJavaStubs/>` / `Generator.CreateJavaSources()`. The `MonoRuntimeInitialization.*.java` files have been moved from Java.Interop into the xamarin-android repo, leaving them as-is. Finally, as `Java.Interop.Tools.JavaCallableWrappers.dll` no longer contains the `MonoRuntimeProvider.*.java` resources, there is no need to extract them anymore: * The `<CopyResource/>` MSBuild task now looks in the executing assembly and not `Java.Interop.Tools.JavaCallableWrappers.dll`. * The`<GenerateJavaStubs/>` MSBuild task likewise just looks in the executing assembly.
cc2fba0
to
f8857b8
Compare
@jonpryor @dellis1972 this is probably ready for first review. The 1 test failure on Windows is another random failure. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we be putting the BundleTool logic and targets in their own file like we are currently doing for Aapt and Aapt2? Is that even possible?
src/Xamarin.Android.Build.Tasks/Tasks/BundleToolInstallApkSet.cs
Outdated
Show resolved
Hide resolved
f8857b8
to
89c1eb8
Compare
src/Xamarin.Android.Build.Tasks/Resources/MonoRuntimeProvider.Shared.20.java
Outdated
Show resolved
Hide resolved
89c1eb8
to
60c4bed
Compare
Restarting the They seem to work for me locally, so trying again once. |
Context: dotnet#2727 This is a prototype that gets us this far: * We generate a `.aab` file * We can generate a `.apks` file specific for an attached device * We can *install* the `.apks` file * The app starts successfully! This workflow is achieved by: * The `<Aapt2Link/>` MSBuild task needs to pass `--proto-format`. * The `<BuildBaseAppBundle/>` and `<BuildAppBundle/>` MSBuild tasks run instead of `<BuildApk/>`. * The `<BuildApkSet/>` and `<InstallApkSet/>` tasks run instead of `adb install`. These are somewhat odd, but they use the attached device to decide which format APK set is needed. Otherwise the APK set was 200MB! Some notes about Android App Bundles: * App bundles use `android:extractNativeLibs="false"`, unless the target device's API level is too low. * `$(AndroidUseAapt2)` is required. * `$(EmbedAssembliesIntoApk)` is required. * `$(_EmbeddedDSOsEnabled)` is required, regardless of `android:extractNativeLibs` value in `AndroidManifest.xml`. * `$(AndroidUseApkSigner)` is turned off. * `$(AndroidUseSharedRuntime)` is turned off. ~~ MonoRuntimeProvider ~~ Some changes were needed in `MonoRuntimeProvider.Bundled.java` in java.interop to move some Java source files to this repo: dotnet/java-interop#422 We need the "split apks" to be in the list of APKs by calling `ApplicationInfo.splitPublicSourceDirs`: https://developer.android.com/reference/android/content/pm/ApplicationInfo.html#splitPublicSourceDirs These are supported on API 21 and higher, so I had to create 4 `.java` files: * `MonoRuntimeProvider.Bundled.java` * `MonoRuntimeProvider.Bundled.20.java` * `MonoRuntimeProvider.Shared.java` * `MonoRuntimeProvider.Shared.20.java` I also extracted `MonoRuntimeProvider.Shared*.java` in `_AddStaticResources`. We should remove the equivalent in monodroid, to keep the code that *extracts* this file in the same repo. I also removed `Xamarin.Android.Platform`, which is a dead package we don't need code for anymore.
60c4bed
to
84c40f1
Compare
Test run is failing to install the AAB:
Something with the java path isn't right on macOS. |
So the app bundle tests look good now:
We did get a crash in the
|
ApkSet="$(_ApkSetIntermediate)" | ||
/> | ||
</Target> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dellis1972 it looks like I could put this target in a new file easily, but is that too little to warrant a new file?
BaseZip="$(_BaseZipIntermediate)" | ||
Output="$(_AppBundleIntermediate)" | ||
UncompressedFileExtensions="$(AndroidStoreUncompressedFileExtensions)" | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could move these to the new file and use <CallTarget/>
, but it wouldn't be able to use this:
<Output TaskParameter="NativeLibrariesReferences" ItemName="_AdditionalNativeLibraryReferences" />
Context: #2727
This is a prototype that gets us this far:
.aab
file.apks
file specific for an attached device.apks
fileThis workflow is achieved by:
<Aapt2Link/>
MSBuild task needs to pass--proto-format
.<AppBundleBaseZip/>
and<BundleToolBuildBundle/>
MSBuildtasks run instead of
<BuildApk/>
.<BundleToolBuildApkSet/>
and<BundleToolInstallApkSet/>
tasks run instead of
adb install
. These are somewhat odd, but theyuse the attached device to decide which format APK set is needed.
Otherwise the APK set was 200MB!
Some notes about Android App Bundles:
android:extractNativeLibs="false"
, unless thetarget device's API level is too low.
$(AndroidUseAapt2)
is required.$(EmbedAssembliesIntoApk)
is required.$(_EmbeddedDSOsEnabled)
is required, regardless ofandroid:extractNativeLibs
value inAndroidManifest.xml
.$(AndroidUseApkSigner)
is turned off.$(AndroidUseSharedRuntime)
is turned off.Java.Interop
Some changes are needed in
MonoRuntimeProvider.Bundled.java
injava.interop before we can merge this.
We need the "split apks" to be in the list of APKs by calling
ApplicationInfo.splitPublicSourceDirs
:https://developer.android.com/reference/android/content/pm/ApplicationInfo.html#splitPublicSourceDirs