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

[BUG][Android] Crash when CarouselView is nested in a ScrollView, inside a TabViewItem (XCT) #592

Open
Kapusch opened this issue Mar 13, 2021 · 6 comments

Comments

@Kapusch
Copy link

Kapusch commented Mar 13, 2021

Description

Hello @alexrainman , I have been using your component for a few months, after I've got rid off the official CarouselView (so many events issues...) and I have to say : thank you very much for your great library !

But the thing is I am now using the Xamarin.CommunityToolkit (XCT) library so that I can navigate to my pages with bottom tabs. And my app is getting crashed every time I try to display your CarouselView inside a ScrollView.

I am actually having a java.lang.StackOverflowError :

Expand Stacktrace
[Mono] Assembly Ref addref CarouselView.FormsPlugin.Droid[0xce8f4de0] -> Java.Interop[0xce5c9d80]: 22
[w_stackoverflo] java_vm_ext.cc:570] JNI DETECTED ERROR IN APPLICATION: JNI GetObjectClass called with pending exception java.lang.StackOverflowError: stack size 8192KB
[w_stackoverflo] java_vm_ext.cc:570]   at void crc6414252951f3f66c67.CarouselViewAdapter_2.n_onBindViewHolder(androidx.recyclerview.widget.RecyclerView$ViewHolder, int) (CarouselViewAdapter_2.java:-2)
[w_stackoverflo] java_vm_ext.cc:570]   at void crc6414252951f3f66c67.CarouselViewAdapter_2.onBindViewHolder(androidx.recyclerview.widget.RecyclerView$ViewHolder, int) (CarouselViewAdapter_2.java:38)
[w_stackoverflo] java_vm_ext.cc:570]   at void androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(androidx.recyclerview.widget.RecyclerView$ViewHolder, int, java.util.List) (RecyclerView.java:7065)
[w_stackoverflo] java_vm_ext.cc:570]   at void androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(androidx.recyclerview.widget.RecyclerView$ViewHolder, int) (RecyclerView.java:7107)
[w_stackoverflo] java_vm_ext.cc:570]   at boolean androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(androidx.recyclerview.widget.RecyclerView$ViewHolder, int, int, long) (RecyclerView.java:6012)
[w_stackoverflo] java_vm_ext.cc:570]   at androidx.recyclerview.widget.RecyclerView$ViewHolder androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(int, boolean, long) (RecyclerView.java:6279)
[w_stackoverflo] java_vm_ext.cc:570]   at android.view.View androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(int, boolean) (RecyclerView.java:6118)
[w_stackoverflo] java_vm_ext.cc:570]   at android.view.View androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(int) (RecyclerView.java:6114)
[w_stackoverflo] java_vm_ext.cc:570]   at android.view.View androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(androidx.recyclerview.widget.RecyclerView$Recycler) (LinearLayoutManager.java:2303)
[w_stackoverflo] java_vm_ext.cc:570]   at void androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(androidx.recyclerview.widget.RecyclerView$Recycler, androidx.recyclerview.widget.RecyclerView$State, androidx.recyclerview.widget.LinearLayoutManager$LayoutState, androidx.recyclerview.widget.LinearLayoutManager$LayoutChunkResult) (LinearLayoutManager.java:1627)
[w_stackoverflo] java_vm_ext.cc:570]   at int androidx.recyclerview.widget.LinearLayoutManager.fill(androidx.recyclerview.widget.RecyclerView$Recycler, androidx.recyclerview.widget.LinearLayoutManager$LayoutState, androidx.recyclerview.widget.RecyclerView$State, boolean) (LinearLayoutManager.java:1587)
[w_stackoverflo] java_vm_ext.cc:570]   at void androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(androidx.recyclerview.widget.RecyclerView$Recycler, androidx.recyclerview.widget.RecyclerView$State) (LinearLayoutManager.java:640)
[w_stackoverflo] java_vm_ext.cc:570]   at void androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2() (RecyclerView.java:4134)
[w_stackoverflo] java_vm_ext.cc:570]   at void androidx.recyclerview.widget.RecyclerView.dispatchLayout() (RecyclerView.java:3851)
[w_stackoverflo] java_vm_ext.cc:570]   at void androidx.recyclerview.widget.RecyclerView$Adapter.bindViewH03-13 12:05:07.875 F/w_stackoverflo(12828): java_vm_ext.cc:570]   at void androidx.recyclerview.widget.RecyclerView.onLayout(boolean, int, int, int, int) (RecyclerView.java:4404)
[w_stackoverflo] java_vm_ext.cc:570]   at void crc643f46942d9dd1fff9.ItemsViewRenderer_3.n_onLayout(boolean, int, int, int, int) (ItemsViewRenderer_3.java:-2)
[w_stackoverflo] java_vm_ext.cc:570]   at void crc643f46942d9dd1fff9.ItemsViewRenderer_3.onLayout(boolean, int, int, int, int) (ItemsViewRenderer_3.java:45)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.View.layout(int, int, int, int) (View.java:22160)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.ViewGroup.layout(int, int, int, int) (ViewGroup.java:6402)
[w_stackoverflo] 03-13 12:05:07.875 F/w_stackoverflo(12828): java_vm_ext.cc:570]   at void crc643f46942d9dd1fff9.Platform_DefaultRenderer.n_onLayout(boolean, int, int, int, int) (Platform_DefaultRenderer.java:-2)
[w_stackoverflo] java_vm_ext.cc:570]   at void crc643f46942d9dd1fff9.Platform_DefaultRenderer.onLayout(boolean, int, int, int, int) (Platform_DefaultRenderer.java:72)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.View.layout(int, int, int, int) (View.java:22160)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.ViewGroup.layout(int, int, int, int) (ViewGroup.java:6402)
[w_stackoverflo] java_vm_ext.cc:570]   at void androidx.recyclerview.widget03-13 12:05:07.875 F/w_stackoverflo(12828): java_vm_ext.cc:570]   at void crc643f46942d9dd1fff9.Platform_DefaultRenderer.n_onLayout(boolean, int, int, int, int) (Platform_DefaultRenderer.java:-2)
[w_stackoverflo] java_vm_ext.cc:570]   at void crc643f46942d9dd1fff9.Platform_DefaultRenderer.onLayout(boolean, int, int, int, int) (Platform_DefaultRenderer.java:72)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.View.layout(int, int, int, int) (View.java:22160)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.ViewGroup.layout(int, int, int, int) (ViewGroup.java:6402)
[w_stackoverflo] java_vm_ext.cc:570]   at void com.xamarin.forms.platform.android.FormsViewGroup.measureAndLayout(int, int, int, int, int, int) (FormsViewGroup.java:37)
[w_stackoverflo] java_vm_ext.cc:570]   at void crc643f46942d9dd1fff9.ItemsViewRenderer_3.onLayout(boolean, int, int, int, int) (ItemsViewRend:07.875 F/w_stackoverflo(12828): java_vm_ext.cc:570]   at void crc643f46942d9dd1fff9.PageRenderer.n_onLayout(boolean, int, int, int, int) (PageRenderer.java:-2)
[w_stackoverflo] java_vm_ext.cc:570]   at void crc643f46942d9dd1fff9.PageRenderer.onLayout(boolean, int, int, int, int) (PageRenderer.java:72)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.View.layout(int, int, int, int) (View.java:22160)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.ViewGroup.layout(int, int, int, int) (ViewGroup.java:6402)
[w_stackoverflo] java_vm_ext.cc:570]   at void com.xamarin.forms.platform.android.FormsViewGroup.measureAndLayout(int, int, int, int, int, int) (FormsViewGroup.java:37)
[w_stackoverflo] java_vm_ext.cc:570]   at void crc643f46942d9dd1fff9.PlatformRenderer.n_onLayout(boolean, int, int, int, int) (PlatformRenderer.java:-2)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.View.layout(int, int, int, int) (View.java:22160)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.ViewGroup.layout(int, int, int, int) (ViewGroup.java:6402)
[w_stackoverflo] java_vm_03-13 12:05:07.875 F/w_stackoverflo(12828): java_vm_ext.cc:570]   at void android.widget.RelativeLayout.onLayout(boolean, int, int, int, int) (RelativeLayout.java:1103)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.View.layout(int, int, int, int) (View.java:22160)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.ViewGroup.layout(int, int, int, int) (ViewGroup.java:6402)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.View.layout(int, int, int, int) (View.java:22160)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.ViewGroup.layout(int, int, int, int) (ViewGroup.java:6402)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.widget.FrameLayout.layoutChildren(int, int, int, int, boolean) (FrameLayout.java:332)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.widget.FrameLayout.onLayout(boolean, int, int, int, int) (FrameLayout.java:270)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.View.layout(int, int, int, int) (View.java:22160)
[w_stackoverfl03-13 12:05:07.876 F] java_vm_ext.cc:570]   at void android.view.ViewGroup.layout(int, int, int, int) (ViewGroup.java:6402)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.widget.FrameLayout.layoutChildren(int, int, int, int, boolean) (FrameLayout.java:332)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.widget.FrameLayout.onLayout(boolean, int, int, int, int) (FrameLayout.java:270)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.View.layout(int, int, int, int) (View.java:22160)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.ViewGroup.layout(int, int, int, int) (ViewGroup.java:6402)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.widget.LinearLayout.setChildFrame(android.view.View, int, int, int, int) (LinearLayout.java:1829)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.widget.FrameLayout.layoutChildren(int, int, int, int, boolean) 03-13 12:05:07.876 F/w_stackoverflo(12828): java_vm_ext.cc:570]   at void android.widget.LinearLayout.layoutVertical(int, int, int, int) (LinearLayout.java:1673)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.View.layout(int, int, int, int) (View.java:22160)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.Vi03-13 12:05:07.876 F/w_stackoverflo(12828): java_vm_ext.cc:570]   at void android.view.ViewGroup.layout(int, int, int, int) (ViewGroup.java:6402)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.widget.FrameLayout.layoutChildren(int, int, int, int, boolean) (FrameLayout.java:332)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.widget.FrameLayout.onLayout(boolean, int, int, int, int) (FrameLayout.java:270)
[w_stackoverflo] java_vm_ext.cc:570]   at void com.android.internal.policy.DecorView.onLayout(boolean, int, int, int, int) (DecorView.java:810)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.ViewGroup.layout(int, int, int, int) (ViewGroup.java:6402)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.ViewRootImpl.performLayout(android.view.WindowManager$LayoutParams, int, int) (ViewRootImpl.java:3330)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.ViewRootImpl.performTraversals() (ViewRootImpl.java:2826)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.03-13 12:05:07.876 F/w_stackoverflo(12828): java_vm_ext.cc:570]   at void android.view.ViewRootImpl.doTraversal() (ViewRootImpl.java:1901)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.ViewRootImpl$TraversalRunnable.run() (ViewRootImpl.java:8066)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.Choreographer$CallbackRecord.run(long) (Choreographer.java:1041)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.Choreographer.doCallbacks(int, long) (Choreographer.java:860)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.Choreographer.doFrame(long, int) (Choreographer.java:785)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.view.Choreographer$FrameDisplayEventReceiver.run() (Choreographer.java:1026)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.os.Handler.handleCallback(android.os.Message) (Handler.java:914)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:100)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.os.Looper.loop() (Looper.java:225)
[w_stackoverflo] java_vm_ext.cc:570]   at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:7563)
[w_stackoverflo] java_vm_ext.cc:570]   at void com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run() (RuntimeInit.java:539)
[w_stackoverflo] java_vm_ext.cc:570]   at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:994)
[w_stackoverflo] java_vm_ext.cc:570] 
[w_stackoverflo] java_vm_ext.cc:570]     in call to GetObjectClass
[w_stackoverflo] java_vm_ext.cc:570]     from void crc6414252951f3f66c67.CarouselViewAdapter_2.n_onBindViewHolder(androidx.recyclerview.widget.RecyclerView$ViewHolder, int)

I have tried to catch the error by debugging both Xamarin.CommunityToolkit and your CarouselView library, but I was only getting a crash without having being able to get a hint...

Also, I can see a related issue #560 which seems to be fixed in 6.0.0.
Then I may think that your fix works if the content is loaded in a ContentPage, but maybe not in a ContentView ?

Steps to Reproduce

  1. Run the repo on Android
  2. Clicks on the third tab where it says "ScrollView + Carousel"
  3. You can see the app is crashing and gives a StackOverflowError in Application Output

Basic Information

  • Version with issue: 6.0.0
  • Last known good version: N/A
  • IDE: VS for Mac v8.9.1
  • Platform Target Frameworks:
    • iOS: 14.4
    • Android: 11.0 (R)
  • Nuget Packages:
    • Xamarin.Forms 5.0.0.2012,
    • Xamarin.Essentials 1.6.1,
    • Xamarin.CommunityToolkit 1.1.0-pre2
  • Affected Devices: Redmi 9A, Android 10 (Q)

Workaround

  1. Replacing ScrollView with a grid works fine, but I really need the ScrollView in my page.
  2. Load the tab content in a new page, but I lose the benefit of using bottom tabs.

Reproduction Link

CarouselView_Stackoverflow.zip

@Kapusch
Copy link
Author

Kapusch commented Apr 2, 2021

Maybe it's related to this xamarin/XamarinCommunityToolkit#1104 ?

@Kapusch
Copy link
Author

Kapusch commented Apr 5, 2021

Hi, I actually got the issue from an endless recursive loop in the CarouselViewImplementation.

Indeed, the method Android.App.Activity FindActivity(Context context) is continuously called itself here:

var contextThemeWrapper = _context as Android.Views.ContextThemeWrapper;
if (contextThemeWrapper != null)
{
    return FindActivity(contextThemeWrapper.BaseContext);
}

as it is not able to find the MainActivity :/

Do you think you could have a look at it please @alexrainman ?

@Kapusch
Copy link
Author

Kapusch commented Apr 5, 2021

Here are some logs in case that helps a little bit:

Console logs for a working Carousel controller
-------> Call of FindActivity from CarouselViewRenderer
-------> FindActivity called 1 times
-------> Rercursive call of FindActivity 
-------> FindActivity called 2 times

-------> Call of FindActivity from SetNativeView
-------> FindActivity called 3 times
-------> Rercursive call of FindActivity 
-------> FindActivity called 4 times
Console logs for crashing Carousel controller
-------> Call of FindActivity from CarouselViewRenderer
-------> FindActivity called 1 times
-------> Rercursive call of FindActivity 
-------> FindActivity called 2 times
-------> Rercursive call of FindActivity 
-------> FindActivity called 3 times
-------> Rercursive call of FindActivity 
-------> FindActivity called 4 times
.......
-------> Rercursive call of FindActivity 
-------> FindActivity called a billion times

@Kapusch
Copy link
Author

Kapusch commented Apr 5, 2021

Actually @alexrainman , I think it is because the same object is passed through the recursive call.

Indeed, _context.BaseContext is always passed, so if MainActivity is not found during the first recursive call, then it will trigger an endless loop.

@Kapusch
Copy link
Author

Kapusch commented Apr 6, 2021

Hello @alexrainman , sorry to spam you, but I think I have fixed my issue by replacing

var contextThemeWrapper = _context as Android.Views.ContextThemeWrapper;

with

var contextThemeWrapper = context as Android.Views.ContextThemeWrapper;

But I'm only able to validate the fix by running your demo project...
Actually, I'm not sure if the new NuGet I have generated is valid :/

Could you please help me to understand how to directly refer your source code into my repro project ?

@alexrainman
Copy link
Owner

Isn't var contextThemeWrapper = _context as Android.Views.ContextThemeWrapper; the same as var contextThemeWrapper = context as Android.Views.ContextThemeWrapper;?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants