Skip to content
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

Maui Android Crash CarouselView IndicatorView on navigating second time #11310

Closed
lucianparvu opened this issue Nov 12, 2022 · 7 comments · Fixed by #11346
Closed

Maui Android Crash CarouselView IndicatorView on navigating second time #11310

lucianparvu opened this issue Nov 12, 2022 · 7 comments · Fixed by #11346
Assignees
Labels
area-controls-collectionview CollectionView, CarouselView, IndicatorView fixed-in-7.0.58 Look for this fix in 7.0.58! fixed-in-7.0.100 fixed-in-7.0.101 fixed-in-8.0.0-preview.1.7762 Look for this fix in 8.0.0-preview.1.7762! platform/android 🤖 t/bug Something isn't working

Comments

@lucianparvu
Copy link

Description

Maui Android Crash when there is CarouselView with IndicatorView and navigating second time to the page .

`

        <CarouselView.ItemTemplate>
            <DataTemplate x:DataType="model:ProductFileV2">                    
                <StackLayout>
                    <Frame HasShadow="True"
                   BorderColor="DarkGray"
                   CornerRadius="5"
                   Margin="20"
                   HeightRequest="300"
                   HorizontalOptions="Center"
                   VerticalOptions="CenterAndExpand">
                        <StackLayout>
                            <local:PinchToZoomContainer>
                                <Image Source="{Binding ThumbnailHostPathPublic}"
                               Aspect="AspectFill"
                               HeightRequest="150"
                               WidthRequest="150"
                               HorizontalOptions="Center" />
                            </local:PinchToZoomContainer>
                        </StackLayout>
                    </Frame>
                </StackLayout>                   
                </DataTemplate>
        </CarouselView.ItemTemplate>
    </CarouselView>
    <IndicatorView x:Name="myIndicator"
               IndicatorColor="LightGray"
               SelectedIndicatorColor="DarkGray"
               HorizontalOptions="Center" />

public ObservableCollection ProductFileList { get; set; } = new ObservableCollection();
void LoadProductFiles()
{
if (IsBusyProductFiles) { return; }
IsBusyProductFiles = true;

        Task.Run(async () =>
        {                
            var items = await _ProductService.GetProductFiles(SearchModel);
            Application.Current.Dispatcher.Dispatch(() =>
            {                   
                ProductFileList.Clear();                   
                items?.Where(p => p.ProductFileType?.ProductFileTypeAction == ProductFileTypeAction.IsGallery)?
                                    .OrderBy(p => p.Importance)?
                                    .ToList()?.ForEach(p => ProductFileList.Add(p));

                IsBusyProductFiles = false;
            });
        });
    }

Steps to Reproduce

Link to public reproduction project repository

dont have

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android

Did you find any workaround?

No

Relevant log output

Time	Device Name	Type	PID	Tag	Message
11-12 16:40:11.425	pixel_5_-_api_33	Error	1788	AndroidRuntime	android.runtime.JavaProxyThrowable: System.InvalidOperationException: PlatformView cannot be null here
   at Microsoft.Maui.Handlers.ViewHandler`2[[Microsoft.Maui.IIndicatorView, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.Platform.MauiPageControl, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].get_PlatformView()
   at Microsoft.Maui.Handlers.IndicatorViewHandler.OnDisconnectHandler(View platformView)
   at Microsoft.Maui.Handlers.ViewHandler.OnDisconnectHandler(Object platformView)
   at Microsoft.Maui.Handlers.ElementHandler.DisconnectHandler(Object platformView)
   at Microsoft.Maui.Handlers.ElementHandler.Microsoft.Maui.IElementHandler.DisconnectHandler()
   at Microsoft.Maui.Controls.Element.SetHandler(IElementHandler newHandler)
   at Microsoft.Maui.Controls.Element.set_Handler(IElementHandler value)
   at Microsoft.Maui.Controls.VisualElement.Microsoft.Maui.IElement.set_Handler(IElementHandler value)
   at Microsoft.Maui.Platform.ElementExtensions.ToHandler(IElement view, IMauiContext context)
   at Microsoft.Maui.Platform.ElementExtensions.ToPlatform(IElement view, IMauiContext context)
   at Microsoft.Maui.Handlers.LayoutHandler.SetVirtualView(IView view)
   at Microsoft.Maui.Handlers.ViewHandler`2[[Microsoft.Maui.ILayout, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.Platform.LayoutViewGroup, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].SetVirtualView(IElement view)
   at Microsoft.Maui.Controls.Element.SetHandler(IElementHandler newHandler)
   at Microsoft.Maui.Controls.Element.set_Handler(IElementHandler value)
   at Microsoft.Maui.Controls.VisualElement.Microsoft.Maui.IElement.set_Handler(IElementHandler value)
   at Microsoft.Maui.Platform.ElementExtensions.ToHandler(IElement view, IMauiContext context)
   at Microsoft.Maui.Platform.ElementExtensions.ToPlatform(IElement view, IMauiContext context)
   at Microsoft.Maui.Handlers.ContentViewHandler.UpdateContent(IContentViewHandler handler)
   at Microsoft.Maui.Handlers.ContentViewHandler.MapContent(IContentViewHandler handler, IContentView page)
   at Microsoft.Maui.PropertyMapper`2.<>c__DisplayClass5_0[[Microsoft.Maui.IContentView, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.Handlers.IContentViewHandler, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].<Add>b__0(IElementHandler h, IElement v)
   at Microsoft.Maui.PropertyMapper.UpdatePropertyCore(String key, IElementHandler viewHandler, IElement virtualView)
   at Microsoft.Maui.PropertyMapper.UpdateProperties(IElementHandler viewHandler, IElement virtualView)
   at Microsoft.Maui.Handlers.ElementHandler.SetVirtualView(IElement view)
   at Microsoft.Maui.Handlers.ViewHandler.SetVirtualView(IElement element)
   at Microsoft.Maui.Handlers.ViewHandler`2[[Microsoft.Maui.IContentView, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.Platform.ContentViewGroup, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].SetVirtualView(IView view)
   at Microsoft.Maui.Handlers.ContentViewHandler.SetVirtualView(IView view)
   at Microsoft.Maui.Handlers.ViewHandler`2[[Microsoft.Maui.IContentView, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.Platform.ContentViewGroup, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].SetVirtualView(IElement view)
   at Microsoft.Maui.Controls.Element.SetHandler(IElementHandler newHandler)
   at Microsoft.Maui.Controls.Element.set_Handler(IElementHandler value)
   at Microsoft.Maui.Controls.VisualElement.Microsoft.Maui.IElement.set_Handler(IElementHandler value)
   at Microsoft.Maui.Platform.ElementExtensions.ToHandler(IElement view, IMauiContext context)
   at Microsoft.Maui.Platform.ViewExtensions.ToHandler(IView view, IMauiContext context)
   at Microsoft.Maui.Controls.Platform.Compatibility.ShellContentFragment.OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
   at AndroidX.Fragment.App.Fragment.n_OnCreateView_Landroid_view_LayoutInflater_Landroid_view_ViewGroup_Landroid_os_Bundle_(IntPtr jnienv, IntPtr native__this, IntPtr native_inflater, IntPtr native_container, IntPtr native_savedInstanceState)
   at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLLL_L(_JniMarshal_PPLLL_L callback, IntPtr jnienv, IntPtr klazz, IntPtr p0, IntPtr p1, IntPtr p2)
	at crc640ec207abc449b2ca.ShellContentFragment.n_onCreateView(Native Method)
	at crc640ec207abc449b2ca.ShellContentFragment.onCreateView(ShellContentFragment.java:62)
	at androidx.fragment.app.Fragment.performCreateView(Fragment.java:3104)
	at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:524)
	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
	at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1890)
	at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1808)
	at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1751)
	at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:538)
	at android.os.Handler.handleCallback(Handler.java:942)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loopOnce(Looper.java:201)
	at android.os.Looper.loop(Looper.java:288)
	at android.app.ActivityThread.main(ActivityThread.java:7892)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
@lucianparvu lucianparvu added the t/bug Something isn't working label Nov 12, 2022
@jsuarezruiz jsuarezruiz added area-controls-collectionview CollectionView, CarouselView, IndicatorView platform/android 🤖 labels Nov 14, 2022
@jsuarezruiz jsuarezruiz self-assigned this Nov 14, 2022
@jsuarezruiz jsuarezruiz added this to the Backlog milestone Nov 14, 2022
@ghost
Copy link

ghost commented Nov 14, 2022

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@jsuarezruiz jsuarezruiz moved this to Todo in MAUI SDK Ongoing Dec 1, 2022
@jsuarezruiz jsuarezruiz moved this from Todo to In Progress in MAUI SDK Ongoing Dec 1, 2022
Repository owner moved this from In Progress to Done in MAUI SDK Ongoing Dec 6, 2022
@jaldinger
Copy link

I am getting a "VirtualView cannot be null here" exception when navigating a second time to a page and then clearing and re-adding elements to an ObservableCollection bound to a CollectionView. Only happens on Android and only in the exact moment the first new element is added to the ObservableCollection. Is my issue likely to be related to and/or fixed by this issue?

@Fric-88
Copy link

Fric-88 commented Dec 14, 2022

I am seeing the same issue as @jaldinger "VirtualView cannot be null here" when adding first item to ObservableCollection. Im not 100% sure, but i think this started happening to me after switching to .NET 7

@jaldinger
Copy link

I am seeing the same issue as @jaldinger "VirtualView cannot be null here" when adding first item to ObservableCollection. Im not 100% sure, but i think this started happening to me after switching to .NET 7

Does this happen to you already on the first navigation, or only on the second, like to me?

@Fric-88
Copy link

Fric-88 commented Dec 15, 2022

I am seeing the same issue as @jaldinger "VirtualView cannot be null here" when adding first item to ObservableCollection. Im not 100% sure, but i think this started happening to me after switching to .NET 7

Does this happen to you already on the first navigation, or only on the second, like to me?

It does not happen to me when navigating, but when Invoking an Add in my ViewModel after recieving a PubSub message. This only Happens if the Collection is empty and only on the first element being added.

    [ObservableProperty]
    public ObservableCollection <Template> templates;

    public TemplatesViewModel(TemplatesManager manager)
    {
        Title = "Templates";
        templatesManager = manager;

        //Initial Template listing -> On Page Load
        Task.Run(RefreshTeplatesAsync);

        //Subscibe to Messages
        WeakReferenceMessenger.Default.Register<TemplateSavedMessage>(this, (r, m) =>
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                Templates.Add(m.Value); //Exception happens here
            });
        });

        WeakReferenceMessenger.Default.Register<TemplateDeletedMessage>(this, (r, m) =>
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                Templates.Remove(m.Value);
            });
        });
    }

@espenrl
Copy link
Contributor

espenrl commented Dec 20, 2022

This fixes it for me until it is patched. Based on #12141

           .ConfigureMauiHandlers(handlers =>
            {
#if ANDROID
                handlers.AddHandler(typeof(IndicatorView), typeof(FixCrashIndicatorViewHandler));
#endif
            })

/// <summary>
/// https://github.com/dotnet/maui/pull/12141
/// </summary>
public sealed class FixCrashIndicatorViewHandler : ViewHandler<IIndicatorView, MauiPageControl>, IIndicatorViewHandler
{
    public static readonly IPropertyMapper<IIndicatorView, IIndicatorViewHandler> Mapper = new PropertyMapper<IIndicatorView, IIndicatorViewHandler>(ViewMapper)
    {
        [nameof(IIndicatorView.Count)] = MapCount,
        [nameof(IIndicatorView.Position)] = MapPosition,
        [nameof(IIndicatorView.HideSingle)] = MapHideSingle,
        [nameof(IIndicatorView.MaximumVisible)] = MapMaximumVisible,
        [nameof(IIndicatorView.IndicatorSize)] = MapIndicatorSize,
        [nameof(IIndicatorView.IndicatorColor)] = MapIndicatorColor,
        [nameof(IIndicatorView.SelectedIndicatorColor)] = MapSelectedIndicatorColor,
        [nameof(IIndicatorView.IndicatorsShape)] = MapIndicatorShape
    };

    public static readonly CommandMapper<IIndicatorView, IIndicatorViewHandler> CommandMapper = new(ViewCommandMapper)
    {
    };

    public FixCrashIndicatorViewHandler() : base(Mapper)
    {
    }

    public FixCrashIndicatorViewHandler(IPropertyMapper? mapper)
        : base(mapper ?? Mapper, CommandMapper)
    {
    }

    public FixCrashIndicatorViewHandler(IPropertyMapper? mapper, CommandMapper? commandMapper)
        : base(mapper ?? Mapper, commandMapper ?? CommandMapper)
    {
    }

    IIndicatorView IIndicatorViewHandler.VirtualView => VirtualView;

    MauiPageControl IIndicatorViewHandler.PlatformView => PlatformView;

    protected override MauiPageControl CreatePlatformView()
    {
        return new MauiPageControl(Context);
    }

    protected override void ConnectHandler(MauiPageControl platformView)
    {
        base.ConnectHandler(platformView);

        if (platformView is MauiPageControl pageControl)
            pageControl.SetIndicatorView(VirtualView);
    }

    protected override void DisconnectHandler(MauiPageControl platformView)
    {
        base.DisconnectHandler(platformView);

        if (platformView is MauiPageControl pageControl)
            pageControl.SetIndicatorView(null);
    }

    public static void MapCount(IIndicatorViewHandler handler, IIndicatorView indicator)
    {
        handler.PlatformView.UpdateIndicatorCount();
    }

    public static void MapPosition(IIndicatorViewHandler handler, IIndicatorView indicator)
    {
        handler.PlatformView.UpdatePosition();
    }

    public static void MapHideSingle(IIndicatorViewHandler handler, IIndicatorView indicator)
    {
        handler.PlatformView.UpdateIndicatorCount();
    }

    public static void MapMaximumVisible(IIndicatorViewHandler handler, IIndicatorView indicator)
    {
        handler.PlatformView.UpdateIndicatorCount();
    }

    public static void MapIndicatorSize(IIndicatorViewHandler handler, IIndicatorView indicator)
    {
        handler.PlatformView.ResetIndicators();
    }

    public static void MapIndicatorColor(IIndicatorViewHandler handler, IIndicatorView indicator)
    {
        handler.PlatformView.ResetIndicators();
    }

    public static void MapSelectedIndicatorColor(IIndicatorViewHandler handler, IIndicatorView indicator)
    {
        handler.PlatformView.ResetIndicators();
    }

    public static void MapIndicatorShape(IIndicatorViewHandler handler, IIndicatorView indicator)
    {
        handler.PlatformView.ResetIndicators();
    }
}

@Kremed
Copy link

Kremed commented Dec 31, 2022

This fixes it for me until it is patched. Based on #12141

           .ConfigureMauiHandlers(handlers =>
            {
#if ANDROID
                handlers.AddHandler(typeof(IndicatorView), typeof(FixCrashIndicatorViewHandler));
#endif
            }) ```

Works Great For Me

@ghost ghost locked as resolved and limited conversation to collaborators Jan 30, 2023
@samhouts samhouts added the fixed-in-7.0.58 Look for this fix in 7.0.58! label Feb 16, 2023
@samhouts samhouts modified the milestones: Backlog, .NET 7 + Servicing Feb 16, 2023
@samhouts samhouts added the fixed-in-8.0.0-preview.1.7762 Look for this fix in 8.0.0-preview.1.7762! label Feb 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-controls-collectionview CollectionView, CarouselView, IndicatorView fixed-in-7.0.58 Look for this fix in 7.0.58! fixed-in-7.0.100 fixed-in-7.0.101 fixed-in-8.0.0-preview.1.7762 Look for this fix in 8.0.0-preview.1.7762! platform/android 🤖 t/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants