-
Notifications
You must be signed in to change notification settings - Fork 37
Description
Hey @Redth, we swapped out one of our ListViews in our production application to solve some pretty significant scrolling issues we were having on android (this is a pretty fantastic list control) with this control and are getting a relatively significant crash rate on android.
The root of the problem appears to be the RvViewContainer is trying to add a view as a child when it already has a parent (stack trace below). My initial though is to not add the Native view to the container unless the parent is null. however, following the code paths I am unsure how this view already has a parent this point, I am also unsure of what sort of side effects this will introduce. I was wondering if you have any ideas why this crash is happening and any insight into if the solution below should safely solve it without side effects? I am able to iterate on a couple of solutions in our production app before hardening and committing back.
RvViewContainer.SetUpView
Existing:
public void SetupView(IView view)
{
if (NativeView is null)
NativeView = view.ToPlatform(MauiContext);
if (VirtualView is null)
{
VirtualView = view;
AddView(NativeView);
}
}Proposed
if (NativeView is null)
{
NativeView = view.ToPlatform(MauiContext);
}
if (NativeView.Parent is null)
{
AddView(NativeView);
}
if (VirtualView is null)
{
VirtualView = view;
}or probably event better
if (NativeView is null)
{
NativeView = view.ToPlatform(MauiContext);
AddView(NativeView);
}
if (VirtualView is null)
{
VirtualView = view;
}Stack trace:
Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod(JniObjectReference , JniObjectReference , JniMethodInfo , JniArgumentValue* )
Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualVoidMethod(String , IJavaPeerable , JniArgumentValue* )
Android.Views.ViewGroup.AddView(View )
Microsoft.Maui.RvViewContainer.SetupView(IView view)
Microsoft.Maui.RvItemHolder.SetupView(IView view)
Microsoft.Maui.RvAdapter.OnBindViewHolder(ViewHolder holder, Int32 position)
AndroidX.RecyclerView.Widget.RecyclerView.Adapter.n_OnBindViewHolder_Landroidx_recyclerview_widget_RecyclerView_ViewHolder_I(IntPtr jnienv, IntPtr native__this, IntPtr native_holder, Int32 position)
Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLI_V(_JniMarshal_PPLI_V callback, IntPtr jnienv, IntPtr klazz, IntPtr p0, Int32 p1)
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
android.view.ViewGroup.addViewInner ViewGroup.java:5295
android.view.ViewGroup.addView ViewGroup.java:5124
android.view.ViewGroup.addView ViewGroup.java:5064
android.view.ViewGroup.addView ViewGroup.java:5036
crc64df4fefb1dda62040.RvAdapter.n_onBindViewHolder(Native Method)
crc64df4fefb1dda62040.RvAdapter.onBindViewHolder RvAdapter.java:60
androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder RecyclerView.java:7678
androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder RecyclerView.java:7761
androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline RecyclerView.java:6582
androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline RecyclerView.java:6848
androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition RecyclerView.java:6688
androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition RecyclerView.java:6684
androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next LinearLayoutManager.java:2362
androidx.recyclerview.widget.LinearLayoutManager.layoutChunk LinearLayoutManager.java:1662
androidx.recyclerview.widget.LinearLayoutManager.fill LinearLayoutManager.java:1622
androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren LinearLayoutManager.java:687
androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2 RecyclerView.java:4604
androidx.recyclerview.widget.RecyclerView.dispatchLayout RecyclerView.java:4307
androidx.recyclerview.widget.RecyclerView.onLayout RecyclerView.java:4873
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
androidx.swiperefreshlayout.widget.SwipeRefreshLayout.onLayout SwipeRefreshLayout.java:689
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
android.widget.FrameLayout.layoutChildren FrameLayout.java:332
android.widget.FrameLayout.onLayout FrameLayout.java:270
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
crc6452ffdc5b34af3a0f.LayoutViewGroup.n_onLayout(Native Method)
crc6452ffdc5b34af3a0f.LayoutViewGroup.onLayout LayoutViewGroup.java:67
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
crc6452ffdc5b34af3a0f.ContentViewGroup.n_onLayout(Native Method)
crc6452ffdc5b34af3a0f.ContentViewGroup.onLayout ContentViewGroup.java:67
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
crc640ec207abc449b2ca.ShellPageContainer.n_onLayout(Native Method)
crc640ec207abc449b2ca.ShellPageContainer.onLayout ShellPageContainer.java:58
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
android.widget.FrameLayout.layoutChildren FrameLayout.java:332
android.widget.FrameLayout.onLayout FrameLayout.java:270
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
androidx.recyclerview.widget.RecyclerView$LayoutManager.layoutDecoratedWithMargins RecyclerView.java:10321
androidx.recyclerview.widget.LinearLayoutManager.layoutChunk LinearLayoutManager.java:1720
androidx.recyclerview.widget.LinearLayoutManager.fill LinearLayoutManager.java:1622
androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren LinearLayoutManager.java:687
androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2 RecyclerView.java:4604
androidx.recyclerview.widget.RecyclerView.dispatchLayout RecyclerView.java:4307
androidx.recyclerview.widget.RecyclerView.onLayout RecyclerView.java:4873
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
androidx.viewpager2.widget.ViewPager2.onLayout ViewPager2.java:527
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
com.google.android.material.appbar.HeaderScrollingViewBehavior.layoutChild HeaderScrollingViewBehavior.java:149
com.google.android.material.appbar.ViewOffsetBehavior.onLayoutChild ViewOffsetBehavior.java:43
com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior.onLayoutChild AppBarLayout.java:2376
androidx.coordinatorlayout.widget.CoordinatorLayout.onLayout CoordinatorLayout.java:953
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
android.widget.FrameLayout.layoutChildren FrameLayout.java:332
android.widget.FrameLayout.onLayout FrameLayout.java:270
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
android.widget.LinearLayout.setChildFrame LinearLayout.java:1891
android.widget.LinearLayout.layoutVertical LinearLayout.java:1729
android.widget.LinearLayout.onLayout LinearLayout.java:1638
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
android.widget.FrameLayout.layoutChildren FrameLayout.java:332
android.widget.FrameLayout.onLayout FrameLayout.java:270
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
androidx.drawerlayout.widget.DrawerLayout.onLayout DrawerLayout.java:1273
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
android.widget.LinearLayout.setChildFrame LinearLayout.java:1891
android.widget.LinearLayout.layoutHorizontal LinearLayout.java:1880
android.widget.LinearLayout.onLayout LinearLayout.java:1640
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
android.widget.FrameLayout.layoutChildren FrameLayout.java:332
android.widget.FrameLayout.onLayout FrameLayout.java:270
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
android.widget.FrameLayout.layoutChildren FrameLayout.java:332
android.widget.FrameLayout.onLayout FrameLayout.java:270
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
android.widget.FrameLayout.layoutChildren FrameLayout.java:332
android.widget.FrameLayout.onLayout FrameLayout.java:270
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
android.widget.LinearLayout.setChildFrame LinearLayout.java:1891
android.widget.LinearLayout.layoutVertical LinearLayout.java:1729
android.widget.LinearLayout.onLayout LinearLayout.java:1638
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
android.widget.FrameLayout.layoutChildren FrameLayout.java:332
android.widget.FrameLayout.onLayout FrameLayout.java:270
com.android.internal.policy.DecorView.onLayout DecorView.java:807
android.view.View.layout View.java:25159
android.view.ViewGroup.layout ViewGroup.java:6460
android.view.ViewRootImpl.performLayout ViewRootImpl.java:4562
android.view.ViewRootImpl.performTraversals ViewRootImpl.java:3830
android.view.ViewRootImpl.doTraversal ViewRootImpl.java:2718
android.view.ViewRootImpl$TraversalRunnable.run ViewRootImpl.java:9937
android.view.Choreographer$CallbackRecord.run Choreographer.java:1406
android.view.Choreographer$CallbackRecord.run Choreographer.java:1415
android.view.Choreographer.doCallbacks Choreographer.java:1015
android.view.Choreographer.doFrame Choreographer.java:945
android.view.Choreographer$FrameDisplayEventReceiver.run Choreographer.java:1389
android.os.Handler.handleCallback Handler.java:959
android.os.Handler.dispatchMessage Handler.java:100
android.os.Looper.loopOnce Looper.java:232
android.os.Looper.loop Looper.java:317
android.app.ActivityThread.main ActivityThread.java:8592
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run RuntimeInit.java:580
com.android.internal.os.ZygoteInit.main ZygoteInit.java:878