react-native: Random crashes when loading two react bundles
Is this a bug report?
Yes
Have you read the Contributing Guidelines?
Yes
Environment
Environment: OS: macOS Sierra 10.12.6 Node: 8.9.0 Yarn: Not Found npm: 5.6.0 Watchman: 4.9.0 Xcode: Not Found Android Studio: 3.0 AI-171.4443003
Packages: (wanted => installed) react: 16.0.0 => 16.0.0 react-native: 0.51.0 => 0.51.0
Target Platform: Adnroid (27)
Steps to Reproduce
It’s difficult to describes steps to reproduce it, because there is a lot of native code here. I basically have a single activity with two bundles on it. I’m using the class ReactInstanceManagerBuilder to create my bundles.
- Create a simple activity
- Instantiate a React Bundle
- Get a RootView from the bundle
- Inflate this RootView into the page
- Instantiate another React Bundle
- Get the RootView from the bundle
- Inflate the RootView 2 into the page
Expected Behavior
Open two bundles in a single Android Activity.
Actual Behavior
It actually opens it. However, I have random crashes when the bundles tries to update its view props.
public void updateShadowNodeProp(
ReactShadowNode nodeToUpdate,
ReactStylesDiffMap props) {
try {
if (mIndex == null) {
SHADOW_ARGS[0] = extractProperty(props);
mSetter.invoke(nodeToUpdate, SHADOW_ARGS);
Arrays.fill(SHADOW_ARGS, null);
} else {
SHADOW_GROUP_ARGS[0] = mIndex;
SHADOW_GROUP_ARGS[1] = extractProperty(props);
mSetter.invoke(nodeToUpdate, SHADOW_GROUP_ARGS);
Arrays.fill(SHADOW_GROUP_ARGS, null);
}
} catch (Throwable t) {
FLog.e(ViewManager.class, "Error while updating prop " + mPropName, t);
throw new JSApplicationIllegalArgumentException("Error while updating property '" +
mPropName + "' in shadow node of type: " + nodeToUpdate.getViewClass(), t);
}
}
This method throws many different exceptions.
Example
com.facebook.react.bridge.JSApplicationIllegalArgumentException: Error while updating property ‘borderBottomWidth’ in shadow node of type: RCTView at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateShadowNodeProp(ViewManagersPropertyCache.java:113) at com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackShadowNodeSetter.setProperty(ViewManagerPropertyUpdater.java:154) at com.facebook.react.uimanager.ViewManagerPropertyUpdater.updateProps(ViewManagerPropertyUpdater.java:58) at com.facebook.react.uimanager.ReactShadowNodeImpl.updateProperties(ReactShadowNodeImpl.java:298) at com.facebook.react.uimanager.UIImplementation.createView(UIImplementation.java:289) at com.facebook.react.uimanager.UIManagerModule.createView(UIManagerModule.java:373) at java.lang.reflect.Method.invoke(Native Method) at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:374) at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:162) at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method) at android.os.Handler.handleCallback(Handler.java:790) at android.os.Handler.dispatchMessage(Handler.java:99) at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:31) at android.os.Looper.loop(Looper.java:164) at com.facebook.react.bridge.queue.MessageQueueThreadImpl$3.run(MessageQueueThreadImpl.java:194) at java.lang.Thread.run(Thread.java:764)
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 8
- Comments: 18
This is happening in latest RN version. It’s not fixed. Can someone reopen this?
@ashutosh-akss The sample code to use local variables is like this:
You need to do repeat this sort of changes in https://github.com/facebook/react-native/blob/0.56-stable/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagersPropertyCache.java#L81-L111
same issue here with latest bundle downloaded today
I’m guessing that this SHADOW_ARGS are causing the problem, since they are static. The code assumes that you have a single thread sequentially.
It’s that true if you have two bundles running? Each one in a different fragment?
In my opinion:
The PropSetter should be per bundle instead of be a static field. Thus, we can avoid extra allocations problems and it will be thread safe.
Another option is to implement a mutex or semaphore, making it really thread safe.