Fix unmount of ReactRootView for Fabric surfaces

Reviewed By: fkgozali

Differential Revision: D7114865

fbshipit-source-id: f0a1c47c983e610fe0dba3051ed8aa350ac052cc
This commit is contained in:
David Vacca 2018-03-01 10:24:19 -08:00 committed by Facebook Github Bot
parent c0c388c8aa
commit 9b3861c109
7 changed files with 88 additions and 4 deletions

View File

@ -9,6 +9,8 @@
*/ */
'use strict'; 'use strict';
const BatchedBridge = require('BatchedBridge');
// TODO @sema: Adjust types // TODO @sema: Adjust types
import type {ReactNativeType} from 'ReactNativeTypes'; import type {ReactNativeType} from 'ReactNativeTypes';
@ -20,4 +22,6 @@ if (__DEV__) {
ReactFabric = require('ReactFabric-prod'); ReactFabric = require('ReactFabric-prod');
} }
BatchedBridge.registerCallableModule('ReactFabric', ReactFabric);
module.exports = (ReactFabric: ReactNativeType); module.exports = (ReactFabric: ReactNativeType);

View File

@ -27,6 +27,7 @@ rn_android_library(
react_native_target("java/com/facebook/react/modules/appregistry:appregistry"), react_native_target("java/com/facebook/react/modules/appregistry:appregistry"),
react_native_target("java/com/facebook/react/modules/core:core"), react_native_target("java/com/facebook/react/modules/core:core"),
react_native_target("java/com/facebook/react/modules/debug:debug"), react_native_target("java/com/facebook/react/modules/debug:debug"),
react_native_target("java/com/facebook/react/modules/fabric:fabric"),
react_native_target("java/com/facebook/react/modules/debug:interfaces"), react_native_target("java/com/facebook/react/modules/debug:interfaces"),
react_native_target("java/com/facebook/react/modules/deviceinfo:deviceinfo"), react_native_target("java/com/facebook/react/modules/deviceinfo:deviceinfo"),
react_native_target("java/com/facebook/react/modules/systeminfo:systeminfo"), react_native_target("java/com/facebook/react/modules/systeminfo:systeminfo"),

View File

@ -71,6 +71,7 @@ import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
import com.facebook.react.devsupport.interfaces.DevSupportManager; import com.facebook.react.devsupport.interfaces.DevSupportManager;
import com.facebook.react.devsupport.interfaces.PackagerStatusCallback; import com.facebook.react.devsupport.interfaces.PackagerStatusCallback;
import com.facebook.react.modules.appregistry.AppRegistry; import com.facebook.react.modules.appregistry.AppRegistry;
import com.facebook.react.modules.fabric.ReactFabric;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.modules.core.DeviceEventManagerModule; import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.core.ReactChoreographer; import com.facebook.react.modules.core.ReactChoreographer;
@ -1033,8 +1034,14 @@ public class ReactInstanceManager {
CatalystInstance catalystInstance) { CatalystInstance catalystInstance) {
Log.d(ReactConstants.TAG, "ReactInstanceManager.detachViewFromInstance()"); Log.d(ReactConstants.TAG, "ReactInstanceManager.detachViewFromInstance()");
UiThreadUtil.assertOnUiThread(); UiThreadUtil.assertOnUiThread();
catalystInstance.getJSModule(AppRegistry.class) if (rootView.isFabric()) {
catalystInstance.getJSModule(ReactFabric.class)
.unmountComponentAtNodeAndRemoveContainer(rootView.getId());
} else {
catalystInstance.getJSModule(AppRegistry.class)
.unmountApplicationComponentAtRootTag(rootView.getId()); .unmountApplicationComponentAtRootTag(rootView.getId());
}
} }
private void tearDownReactContext(ReactContext reactContext) { private void tearDownReactContext(ReactContext reactContext) {

View File

@ -2,6 +2,12 @@
package com.facebook.react.fabric; package com.facebook.react.fabric;
import static android.view.View.MeasureSpec.AT_MOST;
import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.UNSPECIFIED;
import android.util.Log;
import android.view.View;
import com.facebook.infer.annotation.Assertions; import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.JavaOnlyArray; import com.facebook.react.bridge.JavaOnlyArray;
import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactApplicationContext;
@ -235,8 +241,7 @@ public class FabricUIManagerModule implements UIManager {
int widthMeasureSpec = rootView.getWidthMeasureSpec(); int widthMeasureSpec = rootView.getWidthMeasureSpec();
int heightMeasureSpec = rootView.getHeightMeasureSpec(); int heightMeasureSpec = rootView.getHeightMeasureSpec();
rootShadowNode.setStyleWidthAuto(); updateRootView(rootShadowNode, widthMeasureSpec, heightMeasureSpec);
rootShadowNode.setStyleHeightAuto();
mRootShadowNodeRegistry.addNode(rootShadowNode); mRootShadowNodeRegistry.addNode(rootShadowNode);
mUIViewOperationQueue.addRootView(rootTag, rootView, themedRootContext); mUIViewOperationQueue.addRootView(rootTag, rootView, themedRootContext);
@ -257,4 +262,39 @@ public class FabricUIManagerModule implements UIManager {
return rootNode; return rootNode;
} }
/**
* Updates the styles of the {@link ReactShadowNode} based on the Measure specs received by
* parameters.
*/
public void updateRootView(
ReactShadowNode rootCSSNode, int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = View.MeasureSpec.getMode(widthMeasureSpec);
int widthSize = View.MeasureSpec.getSize(widthMeasureSpec);
switch (widthMode) {
case EXACTLY:
rootCSSNode.setStyleWidth(widthSize);
break;
case AT_MOST:
rootCSSNode.setStyleMaxWidth(widthSize);
break;
case UNSPECIFIED:
rootCSSNode.setStyleWidthAuto();
break;
}
int heightMode = View.MeasureSpec.getMode(heightMeasureSpec);
int heightSize = View.MeasureSpec.getSize(heightMeasureSpec);
switch (heightMode) {
case EXACTLY:
rootCSSNode.setStyleHeight(heightSize);
break;
case AT_MOST:
rootCSSNode.setStyleMaxHeight(heightSize);
break;
case UNSPECIFIED:
rootCSSNode.setStyleHeightAuto();
break;
}
}
} }

View File

@ -0,0 +1,14 @@
load("//ReactNative:DEFS.bzl", "rn_android_library", "react_native_target")
rn_android_library(
name = "fabric",
srcs = glob(["**/*.java"]),
provided_deps = [
],
visibility = [
"PUBLIC",
],
deps = [
react_native_target("java/com/facebook/react/bridge:bridge"),
],
)

View File

@ -0,0 +1,18 @@
package com.facebook.react.modules.fabric;
import com.facebook.react.bridge.JavaScriptModule;
/**
* JS module used to execute Fabric specific methods.
* Note: This is a temporary class that will be replaced when Fabric is fully integrated with the
* rest of the modules.
*/
public interface ReactFabric extends JavaScriptModule {
/**
* JS method used to unmount Fabric surfaces.
* @param rootTag {@link int} react tag of Root {@link com.facebook.react.uimanager.ReactShadowNode}
*/
void unmountComponentAtNodeAndRemoveContainer(int rootTag);
}

View File

@ -222,7 +222,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
"Tried to add child that already has a parent! Remove it from its parent first."); "Tried to add child that already has a parent! Remove it from its parent first.");
} }
if (mChildren == null) { if (mChildren == null) {
mChildren = new ArrayList<ReactShadowNodeImpl>(4); mChildren = new ArrayList<>(4);
} }
mChildren.add(i, child); mChildren.add(i, child);
child.mParent = this; child.mParent = this;