xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

System.NullReferenceException: Object reference not set to an instance of an object #4581

Open Transis-Felipe opened 5 years ago

Transis-Felipe commented 5 years ago

This is my suggestion to fix the bug described bellow

\Xamarin.Forms.Core\VisualElement.cs

Actual Code [TypeConverter(typeof(VisibilityConverter))] public bool IsVisible { get { return (bool)GetValue(IsVisibleProperty); } set { SetValue(IsVisibleProperty, value); } }

New Code [TypeConverter(typeof(VisibilityConverter))] public bool IsVisible { get { return IsVisibleProperty != null ? (bool)GetValue(IsVisibleProperty) : false; } set { SetValue(IsVisibleProperty, value); } }

I've updated the code above to prevent the error below.

Xamarin Exception Stack: System.NullReferenceException: Object reference not set to an instance of an object at Xamarin.Forms.BindableObject.GetValue (Xamarin.Forms.BindableProperty property) [0x00016] in <2213e65041254f04b27ae6e57d256a86>:0 at Xamarin.Forms.VisualElement.get_IsVisible () [0x00000] in <2213e65041254f04b27ae6e57d256a86>:0 at Xamarin.Forms.Layout.OnChildMeasureInvalidated (Xamarin.Forms.VisualElement child, Xamarin.Forms.Internals.InvalidationTrigger trigger) [0x00025] in <2213e65041254f04b27ae6e57d256a86>:0 at Xamarin.Forms.Layout.OnChildMeasureInvalidated (System.Object sender, System.EventArgs e) [0x00013] in <2213e65041254f04b27ae6e57d256a86>:0 at Xamarin.Forms.VisualElement.InvalidateMeasureInternal (Xamarin.Forms.Internals.InvalidationTrigger trigger) [0x0001d] in <2213e65041254f04b27ae6e57d256a86>:0 at Xamarin.Forms.Label.OnTextPropertyChanged (Xamarin.Forms.BindableObject bindable, System.Object oldvalue, System.Object newvalue) [0x0002b] in <2213e65041254f04b27ae6e57d256a86>:0 at Xamarin.Forms.BindableObject.SetValueActual (Xamarin.Forms.BindableProperty property, Xamarin.Forms.BindableObject+BindablePropertyContext context, System.Object value, System.Boolean currentlyApplying, Xamarin.Forms.Internals.SetValueFlags attributes, System.Boolean silent) [0x0012a] in <2213e65041254f04b27ae6e57d256a86>:0 at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes, Xamarin.Forms.BindableObject+SetValuePrivateFlags privateAttributes) [0x0015b] in <2213e65041254f04b27ae6e57d256a86>:0 at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value, System.Boolean fromStyle, System.Boolean checkAccess) [0x0003d] in <2213e65041254f04b27ae6e57d256a86>:0 at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value) [0x00000] in <2213e65041254f04b27ae6e57d256a86>:0 at Xamarin.Forms.Label.set_Text (System.String value) [0x00000] in <2213e65041254f04b27ae6e57d256a86>:0 at TransisMobileX.View.Conexao.Conexao+<>cDisplayClass47_0.b__0 () [0x00000] in :0 at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <616e37f9ed964e569785d5d641b4307c>:0 at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr nativethis) [0x00009] in <616e37f9ed964e569785d5d641b4307c>:0 at (wrapper dynamic-method) System.Object.24(intptr,intptr)

samhouts commented 5 years ago

Do you have a sample project that demonstrates the issue? Thanks!

Transis-Felipe commented 5 years ago

I haven't a repro project because I can't never reproduce this error.

I just get data collected with App Center

Transis-Felipe commented 5 years ago

I've created a PR to solve this problem:

https://github.com/xamarin/Xamarin.Forms/pull/4587

PureWeen commented 5 years ago

possibly related https://github.com/xamarin/Xamarin.Forms/pull/380/files https://bugzilla.xamarin.com/show_bug.cgi?id=23940

PureWeen commented 5 years ago

@transis2 I wonder if this is caused by updating the property bound to the labels text off the UI Thread

Do you know what view/vm change your stack trace correlates to? Can you try to ensure that it is only updated on the UI Thread to see if that resolves the issue?

Transis-Felipe commented 5 years ago

This error happens during an thread that is updating the screen and the user press back button or close the app

            System.Threading.Tasks.Task.Run(() => { DoSomeJobs(); });

private void DoSomeJobs()
{
     //MORE CODE HERE....
                Device.BeginInvokeOnMainThread(() =>
                {
                    LABEL.Text = mensagem;
                });
}
PureWeen commented 5 years ago

@transis2 so in theory if you added a check above LABEL.Text = mensagem; to see if the user has navigated back or if the bindingcontext is null would that be a way to work around your exception?

private void DoSomeJobs()
{
     //MORE CODE HERE....
                Device.BeginInvokeOnMainThread(() =>
                {
                    if(Label.BindingContext != null && UserHasntNavigatedBack)
                         LABEL.Text = mensagem;
                });
}
Transis-Felipe commented 5 years ago

Yes! I've already did this test but not work. Not even inserting a Try Catch. It must be something that happens internally that goes out of sync after I send the command. Some kind of binding or render issue.

ghost commented 5 years ago

We have the same errors here. They are seldom and sporadic. CallStack looks like this:

BindableObject.GetValue (Xamarin.Forms.BindableProperty property) VisualElement.get_IsVisible () Layout.OnChildMeasureInvalidated (Xamarin.Forms.VisualElement child, Xamarin.Forms.Internals.InvalidationTrigger trigger) Layout.OnChildMeasureInvalidated (System.Object sender, System.EventArgs e) VisualElement.InvalidateMeasureInternal (Xamarin.Forms.Internals.InvalidationTrigger trigger) Layout.InvalidateLayout () Layout.OnInternalAdded (Xamarin.Forms.View view) Layout.InternalChildrenOnCollectionChanged (System.Object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) ObservableCollection1[T].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs e) ObservableCollection1[T].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedAction action, System.Object item, System.Int32 index) ObservableCollection1[T].InsertItem (System.Int32 index, T item) Collection1[T].Add (T item) TemplateUtilities.OnContentChanged (Xamarin.Forms.BindableObject bindable, System.Object oldValue, System.Object newValue) BindableObject.SetValueActual (Xamarin.Forms.BindableProperty property, Xamarin.Forms.BindableObject+BindablePropertyContext context, System.Object value, System.Boolean currentlyApplying, Xamarin.Forms.Internals.SetValueFlags attributes, System.Boolean silent) BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes, Xamarin.Forms.BindableObject+SetValuePrivateFlags privateAttributes) BindingExpression.ApplyCore (System.Object sourceObject, Xamarin.Forms.BindableObject target, Xamarin.Forms.BindableProperty property, System.Boolean fromTarget) BindingExpression.Apply (System.Boolean fromTarget) BindingExpression+BindingExpressionPart.b49_0 () Thread+RunnableImplementor.Run () IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr nativethis) (wrapper dynamic-method) System.Object.41(intptr,intptr)

samhouts commented 5 years ago

@transis2 @berndu Ok! Can you list the controls that you use on the affected pages? Let's see if we can narrow it down. Thanks!

ghost commented 5 years ago

@samhouts we have tried another way to get rid of the problem and have seen we used a Task.Run in our navigation service that creates the view model and the view (page). After we made sure the creation of the page is in the main thread/ui thread we haven't seen these crashes any more (runs now for one week). A proposal would be to add a "must run on main thread" in InitilizeComponent somehow.

Transis-Felipe commented 5 years ago

I've used only native controls

This is the XAML code of the UI

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:view="clr-namespace:TransisMobileX.View;assembly=TransisMobileX" Title="Sincronização" x:Class="TransisMobileX.View.Conexao.Conexao">

<ContentPage.Content>
    <Grid CompressedLayout.IsHeadless="true">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <view:ViewTitulo Grid.Row="0">
            <x:Arguments>
                <x:String>Conexão Remota</x:String>
                <x:String>&#xE117;</x:String>
            </x:Arguments>
        </view:ViewTitulo>

        <Grid Grid.Row="1" CompressedLayout.IsHeadless="true">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Label Grid.Row="0" HeightRequest="30" x:Name="LBL_MENSAGEM" Text="" VerticalOptions="Start" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center"/>
            <ProgressBar x:Name="ProgressBarGeral" VerticalOptions="Start" Grid.Row="1" Margin="1,0,1,5"/>
            <Grid Grid.Row="2" Padding="10,0,10,0" >
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <Grid.RowDefinitions>
                    <RowDefinition Height="16" />
                    <RowDefinition Height="40" />
                </Grid.RowDefinitions>

                <Label Text="Enviar" Style="{DynamicResource Texto}"/>
                <Switch HorizontalOptions="Start" x:Name="CHK_ENVIA" VerticalOptions="Start" IsToggled="True" Grid.Row="1" Toggled="CHK_ENVIA_Toggled"/>

                <Label Text="Receber" Grid.Column="1" Style="{DynamicResource Texto}"/>
                <Switch HorizontalOptions="Start" x:Name="CHK_RECEBE" VerticalOptions="Start" Grid.Column="1" Grid.Row="1" Toggled="CHK_RECEBE_Toggled"/>

                <Button Text="Iniciar" Grid.Column="2" x:Name="BT_SINCRONIZAR" WidthRequest="165" Grid.Row="1" Clicked="Conexao_Click" Style="{DynamicResource TextoBotao}"/>
            </Grid>
            <StackLayout Grid.Row="3" x:Name="sp_debug" IsVisible="false" Margin="5,0,0,0" >
                <Label Text="Não apagar os itens na web" TextColor="Red"/>
                <Switch HorizontalOptions="Start" x:Name="CHK_DEBUG" VerticalOptions="Start" IsToggled="false"/>
            </StackLayout>
            <Grid Grid.Row="4" x:Name="sp_opcoes" Padding="10,0,10,0" >
                <Grid.RowDefinitions>
                    <RowDefinition Height="17"/>
                    <RowDefinition Height="30"/>
                    <RowDefinition Height="17"/>
                    <RowDefinition Height="30"/>
                </Grid.RowDefinitions>
                <Label Grid.Row="0" Text="Receber em Velocidade Baixa" Style="{DynamicResource Texto}"/>
                <Switch Grid.Row="1" HorizontalOptions="Start" x:Name="CHK_VELOCIDADE_BAIXA"/>

                <Label Grid.Row="2" Text="Tentar novamente se der erro" Style="{DynamicResource Texto}"/>
                <Switch Grid.Row="3" HorizontalOptions="Start" x:Name="CHK_MENSAGEM"/>
            </Grid>
        </Grid>

        <ListView Grid.Row="2" 
                  VerticalOptions="FillAndExpand" 
                  RowHeight="25"
                  x:Name="ListView1" >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid Padding="0,3,0,0" RowSpacing="3">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="0.5"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Label Text="{Binding Name}" Margin="10,0,0,0"/>
                            <Label Text="{Binding MaxValue}" Grid.Column="1" Margin="0,0,20,0"/>
                            <BoxView Color="#cbd5dd" Grid.Row="1" Style="{StaticResource QuebraLinhaBoxView}" Grid.ColumnSpan="2"/>
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</ContentPage.Content>
<ContentPage.ToolbarItems>
    <ToolbarItem Text="Enviar Ped. p/ Email p/ CPD" Order="Secondary" Activated="MenuItemEnviaCPD_Click"/>
</ContentPage.ToolbarItems>

samhouts commented 5 years ago

@samhouts we have tried another way to get rid of the problem and have seen we used a Task.Run in our navigation service that creates the view model and the view (page). After we made sure the creation of the page is in the main thread/ui thread we haven't seen these crashes any more (runs now for one week). A proposal would be to add a "must run on main thread" in InitilizeComponent somehow.

Interesting. I'll tag this for further investigation. Thanks!

Transis-Felipe commented 5 years ago

Look at this similar thread and how they use the same approach (!= null) to fix:

https://github.com/xamarin/Xamarin.Forms/pull/5423/files

Thanks

Phenek commented 4 years ago

Any news on this?

I got a similar issue on a boolean target iOS and Android. Crash randomly, more than hundred time a day on AppCenter!

System.NullReferenceException:
at Xamarin.Forms.BindingExpression.Apply (System.Boolean fromTarget) [0x00027] in D:\a\1\s\Xamarin.Forms.Core\BindingExpression.cs:52

Let me know, Regards,

Phenek commented 1 year ago

Hello Guys,

I just found one case where I had this issue on a Xaml Binding Date.

<Label Text="{Binding Date
               , StringFormat='{}{0:dd}'
               , Source={x:Reference _dayCell}}"
/>

I manage to resolve this by providing a FallBackValue like this

xmlns:sys="clr-namespace:System;assembly=mscorlib"
<Label Text="{Binding Date
               , StringFormat='{}{0:dd}'
               , Source={x:Reference _dayCell}
               , FallbackValue={x:Static sys:DateTime.Now}}"
/>

Hope it will help someone Regards ;)