Bug 59775 - Listiview scroll + Entry = Crash
Summary: Listiview scroll + Entry = Crash
Status: RESOLVED NOT_REPRODUCIBLE
Alias: None
Product: Forms
Classification: Xamarin
Component: Android (show other bugs)
Version: 2.3.5
Hardware: Other Other
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2017-09-26 22:39 UTC by Frank Schwieterman
Modified: 2017-11-06 21:32 UTC (History)
4 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments

Description Frank Schwieterman 2017-09-26 22:39:09 UTC
We get a number of crashes with the same callstack mentioned in https://forums.xamarin.com/discussion/101486/listiview-scroll-entry-crash:

Java.lang.IllegalArgumentException: parameter must be a descendant of this view
At android.view.ViewGroup.offsetRectBetweenParentAndChild (ViewGroup.java:4554)
At android.view.ViewGroup.offsetDescendantRectToMyCoords (ViewGroup.java:4491)
At android.view.ViewRootImpl.scrollToRectOrFocus (ViewRootImpl.java:2664)
At android.view.ViewRootImpl.draw (ViewRootImpl.java:2308)
At android.view.ViewRootImpl.performDraw (ViewRootImpl.java:2257)
At android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:1887)
At android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1004)
At android.view.ViewRootImpl $ TraversalRunnable.run (ViewRootImpl.java:5706)
At android.view.Choreographer $ CallbackRecord.run (Choreographer.java:761)
At android.view.Choreographer.doCallbacks (Choreographer.java:574)
At android.view.Choreographer.doFrame (Choreographer.java:544)
At android.view.Choreographer $ FrameDisplayEventReceiver.run (Choreographer.java:747)
At android.os.Handler.handleCallback (Handler.java:733)
At android.os.Handler.dispatchMessage (Handler.java:95)
At android.os.Looper.loop (Looper.java:136)
At android.app.ActivityThread.main (ActivityThread.java:5136)
At java.lang.reflect.Method.invokeNative (Native Method)
At java.lang.reflect.Method.invoke (Method.java:515)
At com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:819)
At com.android.internal.os.ZygoteInit.main (ZygoteInit.java:635)
At dalvik.system.NativeStart.main (Native Method)
Xamarin caused by: Java.Lang.RuntimeException: parameter must be a descendant of this view
At dalvik.system.NativeStart.main (Native Method)

So far its only been happening on older devices with fewer resources.  Though we haven't been able to put together a consistent repro to submit, it does happen to our customers.  Please review the information in the thread and the attached Stackoverflow post and see if you can do something.
Comment 1 Frank Schwieterman 2017-09-26 22:42:06 UTC
We can repro it consistently running an internal build of our app on a particular device in a particular scenario, but thats not really useful for giving Xamarin something to look at.  Here's our callstack:

> 09/22/2017 05:41:59.577 PM	(Thread 1)	MainActivity	Java.Lang.IllegalArgumentException: parameter must be a descendant of this view
>   --- End of managed Java.Lang.IllegalArgumentException stack trace ---
> java.lang.IllegalArgumentException: parameter must be a descendant of this view
> 	at android.view.ViewGroup.offsetRectBetweenParentAndChild(ViewGroup.java:5216)
> 	at android.view.ViewGroup.offsetDescendantRectToMyCoords(ViewGroup.java:5153)
> 	at android.view.ViewRootImpl.scrollToRectOrFocus(ViewRootImpl.java:3050)
> 	at android.view.ViewRootImpl.draw(ViewRootImpl.java:2681)
> 	at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2611)
> 	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2201)
> 	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1216)
> 	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6678)
> 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
> 	at android.view.Choreographer.doCallbacks(Choreographer.java:590)
> 	at android.view.Choreographer.doFrame(Choreographer.java:560)
> 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)
> 	at android.os.Handler.handleCallback(Handler.java:739)
> 	at android.os.Handler.dispatchMessage(Handler.java:95)
> 	at android.os.Looper.loop(Looper.java:145)
> 	at android.app.ActivityThread.main(ActivityThread.java:5972)
> 	at java.lang.reflect.Method.invoke(Native Method)
> 	at java.lang.reflect.Method.invoke(Method.java:372)
> 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
> 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Comment 2 Frank Schwieterman 2017-09-29 16:44:20 UTC
The issue comes up when there is an Editor in a ListView and that editor is not currently visible in the ListView (when the Editor ends up in the scrap heap).  I have tried extending the ListViewRenderer to attach a AbsListView.Recycler event handler to clear focus as discussed in the SO thread.  I did observe the Recycler is called for list elements, but not for the views in the header (and footer, I assume).  So I should put out the problem scenario for us there is an Editor in the ListView.Header, not just in a ListView row item.
Comment 3 Frank Schwieterman 2017-09-29 21:08:01 UTC
The solution in the stackoverflow thread can be implemented like this:

[assembly: ExportRenderer(typeof(ListView), typeof(SaferListViewRenderer))]
namespace Project.Client.Mobile.Android.Renderers
{
    public class SaferListViewRenderer : ListViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
        {
            base.OnElementChanged(e);

            if (this.Control != null)
            {
                this.Control.Recycler -= ClearViewFocus;
                this.Control.Recycler += ClearViewFocus;
            }
        }

        private void ClearViewFocus(object sender, AbsListView.RecyclerEventArgs args)
        {
            if (args.View.HasFocus)
            {
                args.View.ClearFocus();

                var manager = (InputMethodManager)args.View.Context.GetSystemService(Context.InputMethodService);

                if (manager != null)
                    manager.HideSoftInputFromWindow(args.View.WindowToken, 0);
            }
        }
    }
}

This will help for Editors that are in listview items, but it won't help for editors in the listview header or footer. To deal with that you can turn the header/footer content into listview items using a DataTemplateSelector. This has performance/rendering implications though as you'll probably need to use ListView.HasUnevenRows.

I think Xamarin should put a fix in the framework for this and header/footers, its quite a bad experience for developers to each encounter/fix this themselves.
Comment 4 Jon Douglas [MSFT] 2017-10-03 19:50:01 UTC
Changing product to Forms for visibility.
Comment 5 Paul DiPietro [MSFT] 2017-10-03 20:10:13 UTC
Could you please provide us with a full, minimized reproduction that exhibits the behavior/crash? It would be much appreciated and help us investigate more quickly. Have you also verified that this issue still exists as of 2.4.0 stable?
Comment 6 Frank Schwieterman 2017-10-03 20:13:13 UTC
Personally I haven't been able to repro the issue on my devices.  It happens on some devices in our test lab, and not consistently.  I tried to build a repro app but our test team wasn't able to get it running.  The stackoverflow thread describes how to put together a minimal repro.

We've spent a lot of time getting this issue fixed on our side, its been an expensive bug for us.
Comment 7 Frank Schwieterman 2017-10-03 20:15:43 UTC
Also, having to move things in the ListView.Header to a ListView.Item and using a DataTemplateSelector introduces other challenges related to listview performance and layout.  So the work-around is not a great final solution.
Comment 8 Paul DiPietro [MSFT] 2017-11-06 21:32:07 UTC
As we haven't had any further reports in over a month, we're going to close this for now. If anyone who can reliably reproduce the issue on the latest stable build of Forms, please reopen this with a solution to aid investigation.

Note You need to log in before you can comment on or make changes to this bug.