joplin
joplin copied to clipboard
Regular crash on Android 12 during synchronization
Environment
Joplin version: 2.11.31 Platform: Android 12 OS specifics: LineageOS 19
Steps to reproduce
- Install the most recent version of Joplin
- Configure WebDAV synchronization
- Start synchronization process
After a random time (from 30 seconds to 2-3 minutes) app crashes. It's pretty annoying: some days I couldn't even sync 2-3 notes between desktop and mobile.
Describe what you expected to happen
Synchronization finishes successfully after some time.
Logfile
Joplin debug report doesn't provide any useful information. I also reviewed logs on WebDAV server and haven't found anything suspicious.
With adb logcat
I've managed to catch the moment of crash, though:
07-07 10:47:37.912 14682 14682 D AndroidRuntime: Shutting down VM
07-07 10:47:37.915 14682 14682 E AndroidRuntime: FATAL EXCEPTION: main
07-07 10:47:37.915 14682 14682 E AndroidRuntime: Process: net.cozic.joplin, PID: 14682
07-07 10:47:37.915 14682 14682 E AndroidRuntime: com.facebook.react.bridge.JSApplicationIllegalArgumentException: connectAnimatedNodes: Animated node with tag (child) [50031] does not exist
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.facebook.react.animated.NativeAnimatedNodesManager.connectAnimatedNodes(NativeAnimatedNodesManager.java:369)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.facebook.react.animated.NativeAnimatedModule$16.execute(NativeAnimatedModule.java:800)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.facebook.react.animated.NativeAnimatedModule$ConcurrentOperationQueue.executeBatch(NativeAnimatedModule.java:191)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.facebook.react.animated.NativeAnimatedModule$3.execute(NativeAnimatedModule.java:381)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.facebook.react.uimanager.UIViewOperationQueue$UIBlockOperation.execute(UIViewOperationQueue.java:579)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:915)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:1026)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.facebook.react.uimanager.UIViewOperationQueue.access$2600(UIViewOperationQueue.java:47)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1086)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:175)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:85)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1035)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at android.view.Choreographer.doCallbacks(Choreographer.java:845)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at android.view.Choreographer.doFrame(Choreographer.java:775)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:938)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:201)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at android.os.Looper.loop(Looper.java:288)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7870)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-07 10:47:37.915 14682 14682 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
07-07 10:47:37.920 1354 5639 W ActivityTaskManager: Force finishing activity net.cozic.joplin/.MainActivity
...which has brought me to the upstream bug in react-native: https://github.com/facebook/react-native/issues/33686 https://github.com/facebook/react-native/issues/37267
They said it's specific to Android 12 and isn't resolved yet. Though they've proposed some override, I have no clear idea how to apply it in Joplin.
If animations are disabled globally in settings, does this still happen? (Settings > Accessibility > Visibility Enhancements > Remove animations). I suspect that react-native ignores this setting for most (all?) animations, but it may be worth trying.
Edit: I suspect that this is being caused by the animation for the rotating sync status icon: https://github.com/laurent22/joplin/blob/5405b057920004ace53f9a1249d3dc8d51750303/packages/app-mobile/components/side-menu-content.tsx#L108-L112
Nope :(
Still crashes 100% even with disabled animations (just crashed 2 times in the last 5 minutes).
If animations are disabled globally in settings, does this still happen? (Settings > Accessibility > Visibility Enhancements > Remove animations). I suspect that react-native ignores this setting for most (all?) animations, but it may be worth trying.
Sync status icon does rotating during sync, indeed (though all animations are definitely turned off in system settings, e.g. there is no haptic scroll anymore).
Edit: I suspect that this is being caused by the animation for the rotating sync status icon:
https://github.com/laurent22/joplin/blob/5405b057920004ace53f9a1249d3dc8d51750303/packages/app-mobile/components/side-menu-content.tsx#L108-L112
same problem here! +1
same problem here! +1
I haven't been able to reproduce this locally on an Android 12 emulator. However, I have created two branches with potential fixes.
Potential fix 1: Patching react-native
to use LinkedBlockingQueue
instead of ConcurrentLinkedQueue
This bug was linked to in the upstream react-native issue. ConcurrentLinkedQueue
(one of the data structures used by react-native
to handle animations) drops items in some versions of Android.
The upstream issue suggests patching react-native
and replacing ConcurrentLinkedQueue
with LinkedBlockingQueue
(which may have performance implications).
I've created an APK with these changes applied. It would be helpful if someone could test whether this APK fixes the issue or build from source using the branch with patches applied.
Potential fix 2: Setting useNativeDriver
to false
on Android 12
This issue comment suggests using useNativeDriver: false
to avoid using the native code that throws the exception included above. Without patching dependencies, however, there are only a few places this change can be made:
Note: The rotating "sync" icon is not one of the places we set useNativeDriver: true
and, according to the documentation, this is equivalent to using useNativeDriver: false
. As such, (after searching for usages of useNativeDriver
) it seems that button fade in/out animations seem to be the only place we can change useNativeDriver
from true
to false
without patching dependencies.
Thus, I don't expect this option to fix the issue. However, see this branch for an implementation.
Well... I've just installed fix No 1. So far so good. It's still in process of initial synchronization (it might take an hour as my notes collection is relatively big). No any crash for the last 20 minutes, though. I assume the first approach resolves/overrides the issue successfully.
For second fix - I'll try it later (after the first has finished)
Thanks!!!
Something update? @trap000d
I didn't publish an APK for potential fix 2 (I'm fairly sure it won't work). I plan to open a pull request that applies fix 1 soon, however.
Something update? @trap000d
Nothing new. Fix No 1 works perfectly to me. I've not tried fix 2, though, because there is no APK for it (as @personalizedrefrigerator just mentioned). Unfortunately I had no opportunity to build it from source yet. And I see no point of it (as it most probably will not work).