Skip to content

Commit

Permalink
[android] improve performance of ActivityExtensions.GetWindowFrame (#…
Browse files Browse the repository at this point in the history
…17256)

* [android] improve performance of ActivityExtensions.GetWindowFrame

I've been working to get back some of our lost startup performance on
Android in .NET MAUI. We are really close, a few changes will get .NET 8
on par or faster than .NET 7.

Profiling startup of a `dotnet new maui` app on a Pixel 5,
`dotnet-trace` reported time spent in:

    20.05ms (0.73%)	0.22ns (<0.01%)	microsoft.maui!Microsoft.Maui.Platform.ActivityExtensions.GetWindowFrame(Android.App.Activity)

What is particularly interesting here, is this method is called multiple
times on startup:

* X
* Y
* Width
* Height
* `WindowHandler.ConnectHandler()`

In the future, we should come up with a way the `PropertyMapper` can
somehow "collapse" these calls so we can do it once.

For now, however, I took the following C# code that looks to do 3 Java
interop calls:

    internal static Rect GetWindowFrame(this Android.App.Activity activity)
    {
        var wmc = WindowMetricsCalculator.Companion.OrCreate;
        var wm = wmc.ComputeCurrentWindowMetrics(activity);
        var bounds = wm.Bounds;
        return activity.FromPixels(bounds);
    }

And moved to Java, so we now have 1:

    @nonnull
    public static Rect getCurrentWindowMetrics(Activity activity) {
        return WindowMetricsCalculator.Companion
            .getOrCreate()
            .computeCurrentWindowMetrics(activity)
            .getBounds();
    }

The result being:

    Before:
    20.05ms (0.73%)	0.22ns (<0.01%)	microsoft.maui!Microsoft.Maui.Platform.ActivityExtensions.GetWindowFrame(Android.App.Activity)
    After:
    11.94ms (0.22%)	0.06ns (<0.01%)	microsoft.maui!Microsoft.Maui.Platform.ActivityExtensions.GetWindowFrame(Android.App.Activity)

I'd estimate this might improve startup by ~8ms.

In future .NET releases, we should revisit the `PropertyMapper` pattern.
This could be *even better* if it was only called once.

* Update maui.aar
  • Loading branch information
jonathanpeppers authored Sep 11, 2023
1 parent f04c5af commit 2fb0727
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/Core/AndroidNative/maui/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ dependencies {
annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1'

implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.window:window:1.1.0'
implementation 'com.google.android.material:material:1.4.0'
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.microsoft.maui;

import android.app.Activity;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.BlendMode;
Expand All @@ -10,6 +11,7 @@
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable;
Expand All @@ -35,6 +37,7 @@
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import androidx.window.layout.WindowMetricsCalculator;

import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
Expand Down Expand Up @@ -550,6 +553,19 @@ public static void setLengthFilter(@NonNull EditText editText, int maxLength)
}
}

/**
* Computes the current WindowMetrics' bounds
* @param activity
* @return Rect value of the bounds
*/
@NonNull
public static Rect getCurrentWindowMetrics(Activity activity) {
return WindowMetricsCalculator.Companion
.getOrCreate()
.computeCurrentWindowMetrics(activity)
.getBounds();
}

private static class ColorStates
{
static final int[] EMPTY = new int[] { };
Expand Down
5 changes: 1 addition & 4 deletions src/Core/src/Platform/Android/ActivityExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using AndroidX.Window.Layout;
using Microsoft.Maui.Graphics;

namespace Microsoft.Maui.Platform
Expand All @@ -7,9 +6,7 @@ internal static partial class ActivityExtensions
{
internal static Rect GetWindowFrame(this Android.App.Activity activity)
{
var wmc = WindowMetricsCalculator.Companion.OrCreate;
var wm = wmc.ComputeCurrentWindowMetrics(activity);
var bounds = wm.Bounds;
var bounds = PlatformInterop.GetCurrentWindowMetrics(activity);
return activity.FromPixels(bounds);
}

Expand Down
Binary file modified src/Core/src/maui.aar
Binary file not shown.

0 comments on commit 2fb0727

Please sign in to comment.