-
Notifications
You must be signed in to change notification settings - Fork 559
[Xamarin.Android.Build.Tasks] Fast Deployment v2.0 #4690
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
Conversation
cd83db6
to
fa4a580
Compare
Draft release notes No hurry on adding a draft release notes while this pull request is still in draft and under active revision. I'll leave a first little comment now just to give a starting place for when the pull request is ready to get into the documentation phase. Thanks! Some (probably all obvious) items and questions that might be relevant to cover in the eventual release note:
|
#4643) Changes: xamarin/monodroid@5849ea1...e795bce * xamarin/monodroid@e795bcef3: Bump to xamarin/androidtools@739afe5 (#1095) * xamarin/monodroid@97451721c: [tools/msbuild] add $(_AndroidAllowDeltaInstall) (#1089) Add ***Experimental*** "`.apk` delta installation" support. *What do we want?!* Faster `.apk` installs! (See also PR #4690.) The question, as ever, is *how* to reduce the time of `.apk` installs, and what the tradeoffs are. Fast dev, which removes assemblies from the `.apk`, is one way to do that; PR #4690 is "fastdev v2", which does more there. But for everything else in the `.apk` -- Android Assets, Resources, and more -- how do we make deploying it faster? Here is one way. Android Studio contains an [`installer`][0] utility, built for each supported Android target platform, which is installed onto the target device as `/data/local/tmp/.studio/bin/installer`. `installer` works in terms of "protocol buffers", and can *in place update* an `.apk` file installed on the Android target via a "delta" between the currently installed `.apk` and the "to be installed" `.apk`. `installer` deals with *just* `.apk` contents, and thus doesn't special-case Android Assets, Resources, or IL assemblies. As the `installer` utility is Apache 2 licensed, Xamarin.Android can redistribute and use the `installer` utility as well. To use `installer` to deploy `.apk` updates: 1. Use a Xamarin.Android install which contains `installer` integration, e.g. via `make make prepare-external-git-dependencies` or via a master AzDO-hosted build. 2. Install an app: msbuild /t:Install samples/HelloWorld/HelloWorld.csproj 3. Make a change, e.g. by editing `samples/HelloWorld/Resources/layout/Main.axml`. 4. Install the app, enabling use of this new feature: msbuild /t:Install samples/HelloWorld/HelloWorld.csproj /p:_AndroidAllowDeltaInstall=True This triggers the following in the code: a. Create the `.apk` to deploy, "as normal". b. Check to see if `installer` is present on the Android target. If not, deploy to `/data/local/tmp/.studio/bin/installer`. This happens optimistically, by trying to start up `installer`, looking for certain error codes that indicate the installer isn't present, then installing `installer` if needed. c. Invoke the target's `installer` to obtain the contents of the *currently installed* `.apk` file. d. Compute a diff between (4.c) and the `.apk` in (4.a). e. Deploy the diff to the Android target. f. Invoke `installer` to apply the diff (4.e) to the installed `.apk`, updating its contents to that of (4.a). g. If this process fails for any reason, a "normal" `adb install` is performed. This new workflow is only performed when: * The `$(_AndroidAllowDeltaInstall)` MSBuild Property is True * The App is *already deployed* to the Android target. * The Android target is running API-24 (Android v7.0) or later. Some initial Install timing results for step (4), against a Pixel 3a. Timings are total times, including the build, of which the deploy part takes on the order of 1.5 - 2.5 sec or so: | Test | Normal (s) | Delta (s) | |:----------------------------------------------|--------------:|--------------:| | 18MB APK, fast deploy off, updated 1 assembly | 6.3 | 5.6 | | 9MB APK, fast deploy on, updated 1 resource | 5.6 | 5.3 | [0]: https://android.googlesource.com/platform/tools/base/+/studio-master-dev/deploy/installer
15eb283
to
9138c92
Compare
#4643) Changes: https://github.com/xamarin/monodroid/compare/52312f241428fc78f4d15baaa80b56f85a180427...8d51d0af0572db1583a8ab5ec095bec3046ae476 * xamarin/monodroid@8d51d0af0: Bump to xamarin/androidtools/d16-7@767cfdfe (#1095) * xamarin/monodroid@a0fcae82e: [tools/msbuild] add $(_AndroidAllowDeltaInstall) (#1089) * xamarin/monodroid@781e564e5: [tests] Fix build from xamarin-android (#1093) Add ***Experimental*** "`.apk` delta installation" support. *What do we want?!* Faster `.apk` installs! (See also PR #4690.) The question, as ever, is *how* to reduce the time of `.apk` installs, and what the tradeoffs are. Fast dev, which removes assemblies from the `.apk`, is one way to do that; PR #4690 is "fastdev v2", which does more there. But for everything else in the `.apk` -- Android Assets, Resources, and more -- how do we make deploying it faster? Here is one way. Android Studio contains an [`installer`][0] utility, built for each supported Android target platform, which is installed onto the target device as `/data/local/tmp/.studio/bin/installer`. `installer` works in terms of "protocol buffers", and can *in place update* an `.apk` file installed on the Android target via a "delta" between the currently installed `.apk` and the "to be installed" `.apk`. `installer` deals with *just* `.apk` contents, and thus doesn't special-case Android Assets, Resources, or IL assemblies. As the `installer` utility is Apache 2 licensed, Xamarin.Android can redistribute and use the `installer` utility as well. To use `installer` to deploy `.apk` updates: 1. Use a Xamarin.Android install which contains `installer` integration, e.g. via `make make prepare-external-git-dependencies` or via a master AzDO-hosted build. 2. Install an app: msbuild /t:Install samples/HelloWorld/HelloWorld.csproj 3. Make a change, e.g. by editing `samples/HelloWorld/Resources/layout/Main.axml`. 4. Install the app, enabling use of this new feature: msbuild /t:Install samples/HelloWorld/HelloWorld.csproj /p:_AndroidAllowDeltaInstall=True This triggers the following in the code: a. Create the `.apk` to deploy, "as normal". b. Check to see if `installer` is present on the Android target. If not, deploy to `/data/local/tmp/.studio/bin/installer`. This happens optimistically, by trying to start up `installer`, looking for certain error codes that indicate the installer isn't present, then installing `installer` if needed. c. Invoke the target's `installer` to obtain the contents of the *currently installed* `.apk` file. d. Compute a diff between (4.c) and the `.apk` in (4.a). e. Deploy the diff to the Android target. f. Invoke `installer` to apply the diff (4.e) to the installed `.apk`, updating its contents to that of (4.a). g. If this process fails for any reason, a "normal" `adb install` is performed. This new workflow is only performed when: * The `$(_AndroidAllowDeltaInstall)` MSBuild Property is True * The App is *already deployed* to the Android target. * The Android target is running API-24 (Android v7.0) or later. Some initial Install timing results for step (4), against a Pixel 3a. Timings are total times, including the build, of which the deploy part takes on the order of 1.5 - 2.5 sec or so: | Test | Normal (s) | Delta (s) | |:----------------------------------------------|--------------:|--------------:| | 18MB APK, fast deploy off, updated 1 assembly | 6.3 | 5.6 | | 9MB APK, fast deploy on, updated 1 resource | 5.6 | 5.3 | [0]: https://android.googlesource.com/platform/tools/base/+/studio-master-dev/deploy/installer
a8925ce
to
b205cc8
Compare
ea24767
to
f2f133e
Compare
8a47abe
to
a96c11f
Compare
adfd244
to
1a382ee
Compare
d2d0179
to
4b6fd6b
Compare
Squash-and-merge commit message: Fixes: https://github.com/xamarin/xamarin-android/issues/4996
Fixes: https://github.com/xamarin/xamarin-android/issues/5009
Fixes: https://github.com/xamarin/xamarin-android/issues/5147
Changes: https://github.com/xamarin/monodroid/compare/1ac5333ec5e90b4e1fb9b324714811effdede37f...767f647151936303c294d154d0d0a4da8b601464
* xamarin/monodroid@767f64715: [msbuild] Fast Deployment v2.0 (#1090)
* xamarin/monodroid@0f04ba56d: Merge pull request #1115 from xamarin/remove-xreitem
* xamarin/monodroid@d75341fc3: Remove provisionator file completely
* xamarin/monodroid@b62e8c693: Replace XreItem with supported Xcode and JavaJDK syntax
The Fast Deployment system used for debugging Xamarin.Android apps has
been completely re-written. This is mostly due to changes in Android
which means we can no longer use the external storage directory to
store assemblies.
Fast Deployment works by not including files which change often,
like assemblies, in the actual apk. This means the `.apk` will mostly
not need to be re-installed during a debugging/development session.
Instead the assemblies are "Fast Deployed" to a special directory where
a debug version of our runtime knows where to find them.
Historically this was on the external storage directory such as
/storage/emulated/0/Android/data/com.some.package
/mnt/shell/emulated/0/Android/data/com.some.package
/storage/sdcard/Android/data/com.some.package
With Android 11, these directories are no longer accessible. Instead,
we need to deploy the assemblies into the app's internal `files`
directory. This is usually located in `/data/data/@PACKAGE_NAME@`.
This is not a global writable folder, so we need to use the `run-as`
tool to run all the commands to copy the files into that directory.
The `run-as` tool does not always work on older devices. From this
point on Fast Deployment v2 will only be available on API-21+ devices.
If a certain device does not support the `run-as` tool, then you can
always fall back to debugging without Fast Deployment. While this is
slower, it should still work on most devices.
[`$(AndroidFastDeploymentType)`][0] is still supported. This will
deploy both assemblies, native libraries, typemaps, and `.dex` files to
the `files` directory. Support for Fast Deploying Android resources
and assets was removed in commit f0d565fe, as it required the use of
deprecated API's to work.
The Shared Runtime has also be removed in this new system. Previously,
we used to deploy the BCL and API specific assemblies via separate
`.apk` files. This new system removes the need for that. All the BCL
and API specific assemblies will be deployed to the `files` directory
like all the other assemblies.
The new system is on par with the existing system when it comes to
speed. More improvements are planned in future releases which should
make it much quicker.
Using the `samples\HelloWorld` project these are the performance
differences using `HelloWorld.csproj /restore /t:Install /v:n`:
* Deploy "from Clean"
* v1: 00:00:11.42
* v2: 00:00:11.78 [3% longer]
* Incrementally deploy C#-based change
* v1: 00:00:02.58
* v2: 00:00:02.43 [6% faster]
[0]: https://docs.microsoft.com/en-us/xamarin/android/deploy-test/building-apps/build-properties#androidfastdeploymenttype |
Fixes dotnet#5009 Fixes dotnet#5147 Fixes dotnet#4996 The Fast Deployment system used for debugging Xamarin.Android apps has been completely re-written. This is mostly due to changes in the android OS which means we can no longer use the external storage directory to store assemblies. Fast Deployment works by not including files which change often, like assemblies, in the actual apk. This means the .apk will mostly not need to be re-installed during a debugging/development session. Instead the assemblies are "Fast Deployed" to a special directory where a debug version of our runtime knows where to find them. Historically this was on the external storage directory such as `/storage/emulated/0/Android/data/com.some.package` `/mnt/shell/emulated/0/Android/data/com.some.package` `/storage/sdcard/Android/data/com.some.package` With the advent of Android 11, these directories are no longer accessable. So instead we need to deploy the assemblies into the app internal `files` directory. This is usually located in `/data/data/com.some.package`. This is not a global writable folder, so we need to use the `run-as` tool to run all the commands to copy the files into that diectory. The `run-as` tool does not always work on older devices. So from this point on Fast Deployment will only be available on API 21 devices or newer. If a certain device does not support the `run-as` tool, then you can always fall back to debugging without Fast Deployment. While this is slower, it should still work on most devices. The [Enhanced Fast Deployment](~/android/deploy-test/building-apps/build-properties.md#AndroidFastDeploymentType) mode is still available with this new system. This will deploy both assemblies, native libraries, typemaps and dexes to the `files` directory. Support for Fast Deploying resources and assets via that system was removed in commit [f0d565f](dotnet@f0d565f). This was becuase it required the use of depreicated API's to work. The Shared Runtime has also be removed in this new system. Before we used to deploy the BCL and API specific assemblies via seperate .apks. This new system removes the need for that. All the BCL and API specific assemblies will be deployed to the `files` directory like all the other assemblies. The new system is on par with the existing system when it comes to speed. More improvements are planned in future releases which should make it much quicker. Using the `samples\HelloWorld` project these are the performance differences using `HelloWorld.csproj /restore /t:Install /v:n` Old From Clean Time Elapsed 00:00:11.42 Old C# Change Time Elapsed 00:00:02.58 New From Clean Time Elapsed 00:00:11.78 New C# Change Time Elapsed 00:00:02.43
I always disabled FastDeployment because I use ADB over Wifi most time and had issues in the past. Does this v2 fix it? Does it work fine with the buildin wireless debugging of Android 11? @dellis1972 |
@MagicAndre1981 I'm not sure I can test it and see though :) |
@MagicAndre1981 the new fast dev system doesn't change how the debugger attaches, which seems to be the actual problem with #3018. So the new system should still be able to deploy over wifi, the question is if the debugger can attach. Its possible there might have been fix in the adb port forwarding over wifi that might make it work in the latest sdk versions. |
ok, when will this change be part of VS2019? 16.9? @dellis1972 |
@MagicAndre1981 it will be in 16.9 unless something really bad happens (like it breaks everyone :P). I just tested out Debugging Unit tests on a Wifi connected device (Android 11) with this new system and it all seems to work without any issues :) Those tests don't run inside VS2019 though so it might still be an issue from VS. But they do use the mono SoftDebugger which is what VS uses so it might work. I seem to remember you use custom ROMs, so it will depend on what changes you made to the ROM images. |
I only used custom ROM in past for an older phone, now the Pixel3a supports it officially with Android11. So I'll try it with 16.9 @dellis1972. Hopefully until 16.9, my blocker issue gets also fixed because XF5 will require VS2019 and I have to ditch my VS2017 VM |
Context: dotnet#4690 As of Fast Deployment v2.0 we are no longer using the Shared Runtime packages to fast deploy certain files. It should be safe to remove these from our installers at this time.
Fixes #5009
Fixes #5147
Fixes #4996
The Fast Deployment system used for debugging Xamarin.Android
apps has been completely re-written. This is mostly due to
changes in the android OS which means we can no longer use
the external storage directory to store assemblies.
Fast Deployment works by not including files which change often,
like assemblies, in the actual apk. This means the .apk will
mostly not need to be re-installed during a debugging/development
session. Instead the assemblies are "Fast Deployed" to a special
directory where a debug version of our runtime knows where to find
them.
Historically this was on the external storage directory such as
With the advent of Android 11, these directories are no longer accessable.
So instead we need to deploy the assemblies into the app internal
files
directory. This is usually located in
/data/data/com.some.package
. Thisis not a global writable folder, so we need to use the
run-as
tool torun all the commands to copy the files into that diectory.
The
run-as
tool does not always work on older devices. So from this point onFast Deployment will only be available on API 21 devices or newer. If a certain
device does not support the
run-as
tool, then you can always fall back todebugging without Fast Deployment. While this is slower, it should still work
on most devices.
The Enhanced Fast Deployment mode is still available with this new system.
This will deploy both assemblies, native libraries, typemaps and dexes to the
files
directory. Support for Fast Deploying resources and assets via that system was
removed in commit f0d565fe. This was becuase it required the use of
depreicated API's to work.
The Shared Runtime has also be removed in this new system. Before we used to deploy
the BCL and API specific assemblies via seperate .apks. This new system removes
the need for that. All the BCL and API specific assemblies will be deployed to the
files
directory like all the other assemblies.The new system is on par with the existing system when it comes to speed. More
improvements are planned in future releases which should make it much quicker.
Using the
samples\HelloWorld
project these are the performance differencesusing
HelloWorld.csproj /restore /t:Install /v:n
Old From Clean Time Elapsed 00:00:11.42
Old C# Change Time Elapsed 00:00:02.58
New From Clean Time Elapsed 00:00:11.78
New C# Change Time Elapsed 00:00:02.43