Code Monkey home page Code Monkey logo

Comments (13)

IjzerenHein avatar IjzerenHein commented on June 14, 2024 2

Released as https://github.com/IjzerenHein/react-native-magic-move/releases/tag/v0.6.5

from react-native-magic-move.

rgommezz avatar rgommezz commented on June 14, 2024 2

Thanks very much for the explanation and fix, it makes sense! 🎉

from react-native-magic-move.

IjzerenHein avatar IjzerenHein commented on June 14, 2024 1

Hi, thanks for the extensive bug-report @rgommezz, that's awesome!
I'm quite busy at the moment but I'll try to take a closer look at it later this week.
cheers, Hein

from react-native-magic-move.

IjzerenHein avatar IjzerenHein commented on June 14, 2024 1

Hi, I've managed to repro the problem by updating my example app to use the latest react-navigation. Stay tuned..

from react-native-magic-move.

rgommezz avatar rgommezz commented on June 14, 2024 1

Excellent! I'll do so this weekend. Will keep you updated

from react-native-magic-move.

IjzerenHein avatar IjzerenHein commented on June 14, 2024

Alright, thanks for reporting this, I'm going to take a look 👍

from react-native-magic-move.

rgommezz avatar rgommezz commented on June 14, 2024

Hey @IjzerenHein, first of all lemme tell you that this library is awesome, I've seen your talk and tinkered with the examples and the animations are delightful, well done! 🥇

However, I am experiencing the same issue as @neyosoft:

Configuration

  • Device: Pixel 2 running on Android 9
  • Routing library: react-navigation 3.11.x
  • React-native: 0.60
  • React-native-magic-move: 0.6.2
  • React-navigation-magic-move: 0.4.1
  • Native optimisations: ON

Findings

I've done a little research about it to find a minimum reproduction case.

My findings are quite interesting. The problem arises when you have on your screen some array structure inside render. Let me shed some light.

Having wrapped your entire application with Magic.Provider and imported 'react-navigation-magic-move' on the entry point, imagine the below screen with just a simple MagicMove view:

        <MagicMove.Scene>
            <MagicMove.View
                id={shared}
                style={styles.role}
            >
                <Avatar.Image
                    size={AVATAR_SIZE}
                    source={{uri: imageSrc}}
                />
            </MagicMove.View>
        </MagicMove.Scene>

That works as expected, no issues.

However, changing slightly the structure as below produces the crash:

        <MagicMove.Scene>
            {
                [
                    <MagicMove.View
                        id={shared}
                        style={styles.role}
                    >
                        <Avatar.Image
                            size={AVATAR_SIZE}
                            source={{uri: imageSrc}}
                        />
                    </MagicMove.View>
                ]
            }
        </MagicMove.Scene>

Array structures are the atomic units for both ScrollView and FlatList components, so as long as you have one of those components, you'll likely run into a crash with MagicMove, like:

        <MagicMove.Scene>
            {data.map(item => (
                <MagicMove.View key={item.id} id={id} style={styles.role}>
                    <Avatar.Image
                        size={AVATAR_SIZE}
                        source={{uri: item.imageUri}}
                    />
                </MagicMove.View>
            ))}
        </MagicMove.Scene>

Now, having said that, I have no idea why when you run the JS on chrome V8 (debugging mode on), you don't run into this issue as opposed to JSCore, any ideas? 🤔.

EDIT 2

I've been debugging the Java code. Let me clarify beforehand that I have a very basic Java knowledge. To provide a bit of more context about the error, this is the Java line that triggers the crash

parentView.offsetDescendantRectToMyCoords(sourceView, rawLayout);

And the reason is that sometimes sourceView.mParent == null, so when offsetDescendantRectToMyCoords is called to calculate the offset between parentView and the theoretical descendant sourceView, the exception is thrown because sourceView is not attached to the parent:

 throw new IllegalArgumentException("parameter must be a descendant of this view");

I've tried several options to circumvent the issue, like increasing the delay to re-run uiManager.measureLayout (if it fails), using
uiManager.addUIBlock instead of uiManager.prependUIBlock, even trying to avoid running offsetDescendantRectToMyCoords if for some reason the views are detached and default to some reasonable values.

Also, the crashes are totally random. They happen sometimes, but I can't get a clear indication of what's going on. I also noticed that in release builds, they are reduced to some extent. But I am still able to reproduce it if I repeat a shared transition between screens on a stack navigator 3/4 times.

Of course, I could use the library without the native optimisations, but the experience degrades substantially to the sharp human eye. Without them, I see flickers of the final positions before the animation starts.

I'd be happy to help if I could. When the shared element transitions are working with the native optimisations the result is outstanding, comparable to top of the line native apps. However, I am gonna hold off on the library for now and hopefully in the future someone can find the root cause and put in place a reliable fix

from react-native-magic-move.

IjzerenHein avatar IjzerenHein commented on June 14, 2024

Hi, thanks again for the great feedback and trouble-shooting so far, this really helps a lot! I've begun looking into the problem and will share any updates here. So far, I've been unable to reproduce the problem but I'll keep trying.
Just curious, are you using react-native-screens?

from react-native-magic-move.

rgommezz avatar rgommezz commented on June 14, 2024

Great news @IjzerenHein!

Just in case it's useful for you, I have react-native-screens turned off on Android (for a different reason).

from react-native-magic-move.

IjzerenHein avatar IjzerenHein commented on June 14, 2024

Okay thanks for the info.

Well I've discovered a thing or two. It seems that the problem occurs when magic-move can't measure the layout within the set timeouts. The code retries to measure a couple times and each time a new timeout is started. It's possible that on debug builds (or when running the debugger) this behaves differently, timing wise, due to other things happening as well on the main UI thread.

The measure retry code in Android is not solid enough and can't handle it when layouting takes too long. This needs to be fixed. I'll need to take a closer look on how to solve that as I'm also not a Java/Android expert :)

from react-native-magic-move.

IjzerenHein avatar IjzerenHein commented on June 14, 2024

Hi. I've released a new version in which this problem should be fixed. Could you install it and let me know whether that fixes the problem for you?
You can install it via react-native-magic-move@next.
https://github.com/IjzerenHein/react-native-magic-move/releases/tag/v0.6.4

When confirmed I will release it officially.
cheers

from react-native-magic-move.

rgommezz avatar rgommezz commented on June 14, 2024

I've tested the new version and seems to work like a charm! 🚀

Out of curiosity, how did you end up fixing the problem?

Feel free to close this issue.

Thanks very much, fantastic work!

from react-native-magic-move.

IjzerenHein avatar IjzerenHein commented on June 14, 2024

Awesome, glad to hear that it solved the problem for you! :D :D

Well there are two things that I managed to fix. The first thing was the measure-retry mechanism I mentioned earlier. It tried a max of 3 times to measure and when that didn't work it could crash. That mechanism has been rewritten and it now retries up to a 100 times (max 800ms, just to be sure). Usually it gets it after 4 or 5 retries though. I also added some warnings to that mechanism when measuring takes longer than expected.

The second issue I found was that even though the measure had succeeded, it would still throw parameter must be a descendant of this view very occasionally when calling offsetDescendantRectToMyCoords. This was very strange as the previous call to measure had succeeded. I do have a theory about this and in order to understand that you need to understand what the purpose of offsetDescendantRectToMyCoords was here. That call basically did a second measure, but that measure took into account what the scroll-offset was (which the initial one didn't). The initial uiManager.measureLayout call measured using the RN shadow view-hierarchy and offsetDescendantRectToMyCoords measured using the actual views in the Android view hierarchy. It might have been possible that even though the shadow view-hierarchy was up to date, the actual views, yet weren't. And this caused that call to fail sometimes when a new view was mounted and needed to be added to the view-hierarchy. I then decided to change that part and try to detect the scroll-offset in a safer manor.

from react-native-magic-move.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.