Skip to content

Conversation

@jonathanpeppers
Copy link
Member

Fixes: #1544

I was able to verify that my app's Resource.UpdateIdValues was
getting invoked multiple times with VS 15.7.4:

  • Create a new Xamarin.Android app
  • Create a new Xamarin.Android library, and reference it from the app
  • (Optional) call Android.Runtime.ResourceIdManager.UpdateIdValues
    directly

By placing a breakpoint, and/or Log.Debug messages, I can verify
that my app's Resource.UpdateIdValues was being called 5 times!

The issue lies in this code:

if (id_initialized)
    return;
//System.Reflection code to call Resource.UpdateIdValues() in the app
id_initialized = true;

While Resource.UpdateIdValues is being invoked,
ResourceIdManager.UpdateIdValues () is called recursively.
id_initialized will not be set until after the reflection code has
finished.

The fix is to immediately set the flag:

if (id_initialized)
    return;
id_initialized = true;
//System.Reflection code to call Resource.UpdateIdValues() in the app

I was able to verify the fix in my app:

  • Build the app with xabuild
  • Re-add the Log.Debug message in my app's Resource.UpdateIdValues
  • Deploy the app with xabuild
  • Upon launch, I now only see 1 log message with adb logcat

The performance impact is likely:

  • The reflection code would be slow in
    Android.Runtime.ResourceIdManager.UpdateIdValues
  • In the app's Resource.UpdateIdValues, mostly fields are being read
    and set. It helps to skip this, but it shouldn't be as slow as the
    reflection code.

We should consider this for 15.8 if there is still time.

Fixes: dotnet#1544

I was able to verify that my app's `Resource.UpdateIdValues` was
getting invoked multiple times with VS 15.7.4:
- Create a new Xamarin.Android app
- Create a new Xamarin.Android library, and reference it from the app
- (Optional) call `Android.Runtime.ResourceIdManager.UpdateIdValues`
  directly

By placing a breakpoint, and/or `Log.Debug` messages, I can verify
that my app's `Resource.UpdateIdValues` was being called 5 times!

The issue lies in this code:

    if (id_initialized)
        return;
    //System.Reflection code to call Resource.UpdateIdValues() in the app
    id_initialized = true;

While `Resource.UpdateIdValues` is being invoked,
`ResourceIdManager.UpdateIdValues ()` is called recursively.
`id_initialized` will not be set until after the reflection code has
finished.

The fix is to immediately set the flag:

    if (id_initialized)
        return;
    id_initialized = true;
    //System.Reflection code to call Resource.UpdateIdValues() in the app

I was able to verify the fix in my app:
- Build the app with `xabuild`
- Re-add the `Log.Debug` message in my app's `Resource.UpdateIdValues`
- Deploy the app with `xabuild`
- Upon launch, I *now* only see 1 log message with `adb logcat`

The performance impact is likely:
- The reflection code would be slow in
  `Android.Runtime.ResourceIdManager.UpdateIdValues`
- In the app's `Resource.UpdateIdValues`, mostly fields are being read
  and set. It *helps* to skip this, but it shouldn't be as slow as the
  reflection code.

We should consider this for 15.8 if there is still time.
@jonathanpeppers jonathanpeppers requested a review from jonpryor June 19, 2018 16:26
@jonathanpeppers
Copy link
Member Author

macOS build failing with network issue again, I retried it once:

/Users/builder/jenkins/workspace/xamarin-android-pr-builder/xamarin-android/build-tools/xa-prep-tasks/xa-prep-tasks.targets(91,5): error : 
    Unable to download URL `https://dist.nuget.org/win-x86-commandline/latest/nuget.exe` to `/Users/builder/jenkins/workspace/xamarin-android-pr-builder/xamarin-android/build-tools/xa-prep-tasks/../../.nuget/NuGet.exe`: An error occurred while sending the request [/Users/builder/jenkins/workspace/xamarin-android-pr-builder/xamarin-android/build-tools/xa-prep-tasks/xa-prep-tasks.csproj]

@jonpryor jonpryor merged commit 103b5a7 into dotnet:master Jun 20, 2018
jonathanpeppers added a commit that referenced this pull request Jun 20, 2018
Fixes: #1544

I was able to verify that my app's `Resource.UpdateIdValues()` was
getting invoked multiple times with VS 15.7.4:

  - Create a new Xamarin.Android app
  - Create a new Xamarin.Android library, reference it from the app
  - (Optional) call
    `Android.Runtime.ResourceIdManager.UpdateIdValues()` directly

By placing a breakpoint, and/or `Log.Debug()` messages, I can verify
that my app's `Resource.UpdateIdValues()` was being called 5 times!

The issue lies in this code:

    if (id_initialized)
        return;
    //System.Reflection code to call Resource.UpdateIdValues() in the app
    id_initialized = true;

While `Resource.UpdateIdValues()` is being invoked,
`ResourceIdManager.UpdateIdValues()` is called recursively.  The
`id_initialized` field will not be set until after the reflection
code has finished.

The fix is to immediately set the flag:

    if (id_initialized)
        return;
    id_initialized = true;
    //System.Reflection code to call Resource.UpdateIdValues() in the app

I was able to verify the fix in my app:

  - Build the app with `xabuild`
  - Re-add the `Log.Debug` message in my app's
    `Resource.UpdateIdValues()`
  - Deploy the app with `xabuild`
  - Upon launch, I *now* only see 1 log message with `adb logcat`

The performance impact is likely:

  - The reflection code would be slow in
    `Android.Runtime.ResourceIdManager.UpdateIdValues()`
  - In the app's `Resource.UpdateIdValues()`, mostly fields are being
    read and set. It *helps* to skip this, but it shouldn't be as
    slow as the reflection code.
@jonathanpeppers jonathanpeppers deleted the updateidvalues-called-n-times branch June 20, 2018 20:55
@github-actions github-actions bot locked and limited conversation to collaborators Feb 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Android.Runtime.ResourceIdManager.UpdateIdValues() called multiple times, adds 23 seconds to application startup

2 participants