Use startSurface on Android
Summary: We currently have two different codepaths for actually rendering a surface with Fabric on iOS and Android: on iOS we use Fabric's `UIManagerBinding.startSurface` to call `AppRegistry.runApplication`, but on Android we don't; instead we use the same codepath as paper, calling `ReactRootView.runApplication`. This diff does a few different things: 1. Unify iOS and Android by removing the `#ifndef` for Android so that we call `startSurface` for both 2. Pass through the JS module name on Android so that this actually works (it currently passes in an empty string) 3. Remove the call to `ReactRootView.runApplication` for Fabric so that we don't end up doing this twice 4. Copy over some logic that we need from `ReactRootView.runApplication` (make sure that root layout specs get updated, and that content appeared gets logged) Reviewed By: mdvacca Differential Revision: D15501666 fbshipit-source-id: 5c96c8cf036261cb99729b1dbdff0f7c09a32d76
This commit is contained in:
Родитель
ab1a42762c
Коммит
298f59c5d3
|
@ -1050,16 +1050,24 @@ public class ReactInstanceManager {
|
||||||
private void attachRootViewToInstance(final ReactRoot reactRoot) {
|
private void attachRootViewToInstance(final ReactRoot reactRoot) {
|
||||||
Log.d(ReactConstants.TAG, "ReactInstanceManager.attachRootViewToInstance()");
|
Log.d(ReactConstants.TAG, "ReactInstanceManager.attachRootViewToInstance()");
|
||||||
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "attachRootViewToInstance");
|
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "attachRootViewToInstance");
|
||||||
UIManager uiManagerModule = UIManagerHelper.getUIManager(mCurrentReactContext, reactRoot.getUIManagerType());
|
UIManager uiManager = UIManagerHelper.getUIManager(mCurrentReactContext, reactRoot.getUIManagerType());
|
||||||
|
|
||||||
@Nullable Bundle initialProperties = reactRoot.getAppProperties();
|
@Nullable Bundle initialProperties = reactRoot.getAppProperties();
|
||||||
final int rootTag = uiManagerModule.addRootView(
|
|
||||||
reactRoot.getRootViewGroup(),
|
final int rootTag = uiManager.addRootView(
|
||||||
initialProperties == null ?
|
reactRoot.getRootViewGroup(),
|
||||||
|
initialProperties == null ?
|
||||||
new WritableNativeMap() : Arguments.fromBundle(initialProperties),
|
new WritableNativeMap() : Arguments.fromBundle(initialProperties),
|
||||||
reactRoot.getInitialUITemplate());
|
reactRoot.getInitialUITemplate());
|
||||||
reactRoot.setRootViewTag(rootTag);
|
reactRoot.setRootViewTag(rootTag);
|
||||||
reactRoot.runApplication();
|
if (reactRoot.getUIManagerType() == FABRIC) {
|
||||||
|
// Fabric requires to call updateRootLayoutSpecs before starting JS Application,
|
||||||
|
// this ensures the root will hace the correct pointScaleFactor.
|
||||||
|
uiManager.updateRootLayoutSpecs(rootTag, reactRoot.getWidthMeasureSpec(), reactRoot.getHeightMeasureSpec());
|
||||||
|
reactRoot.setShouldLogContentAppeared(true);
|
||||||
|
} else {
|
||||||
|
reactRoot.runApplication();
|
||||||
|
}
|
||||||
Systrace.beginAsyncSection(
|
Systrace.beginAsyncSection(
|
||||||
TRACE_TAG_REACT_JAVA_BRIDGE,
|
TRACE_TAG_REACT_JAVA_BRIDGE,
|
||||||
"pre_rootView.onAttachedToReactInstance",
|
"pre_rootView.onAttachedToReactInstance",
|
||||||
|
|
|
@ -405,6 +405,21 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWidthMeasureSpec() {
|
||||||
|
return mWidthMeasureSpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHeightMeasureSpec() {
|
||||||
|
return mHeightMeasureSpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShouldLogContentAppeared(boolean shouldLogContentAppeared) {
|
||||||
|
mShouldLogContentAppeared = shouldLogContentAppeared;
|
||||||
|
}
|
||||||
|
|
||||||
private void updateRootLayoutSpecs(final int widthMeasureSpec, final int heightMeasureSpec) {
|
private void updateRootLayoutSpecs(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||||
if (mReactInstanceManager == null) {
|
if (mReactInstanceManager == null) {
|
||||||
FLog.w(
|
FLog.w(
|
||||||
|
@ -461,7 +476,8 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||||
mRootViewEventListener = eventListener;
|
mRootViewEventListener = eventListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ String getJSModuleName() {
|
@Override
|
||||||
|
public String getJSModuleName() {
|
||||||
return Assertions.assertNotNull(mJSModuleName);
|
return Assertions.assertNotNull(mJSModuleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,11 +522,7 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||||
if (mUseSurface) {
|
if (mUseSurface) {
|
||||||
// TODO call surface's runApplication
|
// TODO call surface's runApplication
|
||||||
} else {
|
} else {
|
||||||
|
if (mWasMeasured) {
|
||||||
boolean isFabric = getUIManagerType() == FABRIC;
|
|
||||||
// Fabric requires to call updateRootLayoutSpecs before starting JS Application,
|
|
||||||
// this ensures the root will hace the correct pointScaleFactor.
|
|
||||||
if (mWasMeasured || isFabric) {
|
|
||||||
updateRootLayoutSpecs(mWidthMeasureSpec, mHeightMeasureSpec);
|
updateRootLayoutSpecs(mWidthMeasureSpec, mHeightMeasureSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,9 +532,6 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||||
if (appProperties != null) {
|
if (appProperties != null) {
|
||||||
appParams.putMap("initialProps", Arguments.fromBundle(appProperties));
|
appParams.putMap("initialProps", Arguments.fromBundle(appProperties));
|
||||||
}
|
}
|
||||||
if (isFabric) {
|
|
||||||
appParams.putBoolean("fabric", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
mShouldLogContentAppeared = true;
|
mShouldLogContentAppeared = true;
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class Binding {
|
||||||
ComponentFactoryDelegate componentsRegistry,
|
ComponentFactoryDelegate componentsRegistry,
|
||||||
Object reactNativeConfig);
|
Object reactNativeConfig);
|
||||||
|
|
||||||
public native void startSurface(int surfaceId, NativeMap initialProps);
|
public native void startSurface(int surfaceId, String moduleName, NativeMap initialProps);
|
||||||
|
|
||||||
public native void renderTemplateToSurface(int surfaceId, String uiTemplate);
|
public native void renderTemplateToSurface(int surfaceId, String uiTemplate);
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ import com.facebook.react.fabric.mounting.mountitems.UpdateLocalDataMountItem;
|
||||||
import com.facebook.react.fabric.mounting.mountitems.UpdatePropsMountItem;
|
import com.facebook.react.fabric.mounting.mountitems.UpdatePropsMountItem;
|
||||||
import com.facebook.react.fabric.mounting.mountitems.UpdateStateMountItem;
|
import com.facebook.react.fabric.mounting.mountitems.UpdateStateMountItem;
|
||||||
import com.facebook.react.modules.core.ReactChoreographer;
|
import com.facebook.react.modules.core.ReactChoreographer;
|
||||||
|
import com.facebook.react.uimanager.ReactRoot;
|
||||||
import com.facebook.react.uimanager.ReactRootViewTagGenerator;
|
import com.facebook.react.uimanager.ReactRootViewTagGenerator;
|
||||||
import com.facebook.react.uimanager.StateWrapper;
|
import com.facebook.react.uimanager.StateWrapper;
|
||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
import com.facebook.react.uimanager.ThemedReactContext;
|
||||||
|
@ -127,13 +128,18 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends View> int addRootView(
|
public <T extends View> int addRootView(
|
||||||
final T rootView, final WritableMap initialProps, final @Nullable String initialUITemplate) {
|
final T rootView, final WritableMap initialProps, final @Nullable String initialUITemplate) {
|
||||||
|
return addRootView(rootView, ((ReactRoot) rootView).getJSModuleName(), initialProps, initialUITemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends View> int addRootView(
|
||||||
|
final T rootView, final String moduleName, final WritableMap initialProps, final @Nullable String initialUITemplate) {
|
||||||
final int rootTag = ReactRootViewTagGenerator.getNextRootViewTag();
|
final int rootTag = ReactRootViewTagGenerator.getNextRootViewTag();
|
||||||
ThemedReactContext reactContext =
|
ThemedReactContext reactContext =
|
||||||
new ThemedReactContext(mReactApplicationContext, rootView.getContext());
|
new ThemedReactContext(mReactApplicationContext, rootView.getContext());
|
||||||
mMountingManager.addRootView(rootTag, rootView);
|
mMountingManager.addRootView(rootTag, rootView);
|
||||||
mReactContextForRootTag.put(rootTag, reactContext);
|
mReactContextForRootTag.put(rootTag, reactContext);
|
||||||
mBinding.startSurface(rootTag, (NativeMap) initialProps);
|
mBinding.startSurface(rootTag, moduleName, (NativeMap) initialProps);
|
||||||
if (initialUITemplate != null) {
|
if (initialUITemplate != null) {
|
||||||
mBinding.renderTemplateToSurface(rootTag, initialUITemplate);
|
mBinding.renderTemplateToSurface(rootTag, initialUITemplate);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,9 +45,13 @@ jni::local_ref<Binding::jhybriddata> Binding::initHybrid(
|
||||||
return makeCxxInstance();
|
return makeCxxInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Binding::startSurface(jint surfaceId, NativeMap *initialProps) {
|
void Binding::startSurface(
|
||||||
|
jint surfaceId,
|
||||||
|
jni::alias_ref<jstring> moduleName,
|
||||||
|
NativeMap *initialProps) {
|
||||||
if (scheduler_) {
|
if (scheduler_) {
|
||||||
scheduler_->startSurface(surfaceId, "", initialProps->consume());
|
scheduler_->startSurface(
|
||||||
|
surfaceId, moduleName->toStdString(), initialProps->consume());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,10 @@ class Binding : public jni::HybridClass<Binding>, public SchedulerDelegate {
|
||||||
ComponentFactoryDelegate *componentsRegistry,
|
ComponentFactoryDelegate *componentsRegistry,
|
||||||
jni::alias_ref<jobject> reactNativeConfig);
|
jni::alias_ref<jobject> reactNativeConfig);
|
||||||
|
|
||||||
void startSurface(jint surfaceId, NativeMap *initialProps);
|
void startSurface(
|
||||||
|
jint surfaceId,
|
||||||
|
jni::alias_ref<jstring> moduleName,
|
||||||
|
NativeMap *initialProps);
|
||||||
|
|
||||||
void renderTemplateToSurface(jint surfaceId, jstring uiTemplate);
|
void renderTemplateToSurface(jint surfaceId, jstring uiTemplate);
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ public interface ReactRoot {
|
||||||
*/
|
*/
|
||||||
@Nullable Bundle getAppProperties();
|
@Nullable Bundle getAppProperties();
|
||||||
@Nullable String getInitialUITemplate();
|
@Nullable String getInitialUITemplate();
|
||||||
|
String getJSModuleName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fabric or Default UI Manager, see {@link UIManagerType}
|
* Fabric or Default UI Manager, see {@link UIManagerType}
|
||||||
|
@ -47,4 +48,15 @@ public interface ReactRoot {
|
||||||
* Return native view for root
|
* Return native view for root
|
||||||
*/
|
*/
|
||||||
ViewGroup getRootViewGroup();
|
ViewGroup getRootViewGroup();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Cached values for widthMeasureSpec and heightMeasureSpec
|
||||||
|
*/
|
||||||
|
int getWidthMeasureSpec();
|
||||||
|
int getHeightMeasureSpec();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a flag that determines whether to log that content appeared on next view added.
|
||||||
|
*/
|
||||||
|
void setShouldLogContentAppeared(boolean shouldLogContentAppeared);
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,12 +96,10 @@ void Scheduler::startSurface(
|
||||||
|
|
||||||
shadowTreeRegistry_.add(std::move(shadowTree));
|
shadowTreeRegistry_.add(std::move(shadowTree));
|
||||||
|
|
||||||
#ifndef ANDROID
|
|
||||||
runtimeExecutor_([=](jsi::Runtime &runtime) {
|
runtimeExecutor_([=](jsi::Runtime &runtime) {
|
||||||
uiManagerBinding_->startSurface(
|
uiManagerBinding_->startSurface(
|
||||||
runtime, surfaceId, moduleName, initialProps);
|
runtime, surfaceId, moduleName, initialProps);
|
||||||
});
|
});
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::renderTemplateToSurface(
|
void Scheduler::renderTemplateToSurface(
|
||||||
|
@ -171,11 +169,9 @@ void Scheduler::stopSurface(SurfaceId surfaceId) const {
|
||||||
auto shadowTree = shadowTreeRegistry_.remove(surfaceId);
|
auto shadowTree = shadowTreeRegistry_.remove(surfaceId);
|
||||||
shadowTree->setDelegate(nullptr);
|
shadowTree->setDelegate(nullptr);
|
||||||
|
|
||||||
#ifndef ANDROID
|
|
||||||
runtimeExecutor_([=](jsi::Runtime &runtime) {
|
runtimeExecutor_([=](jsi::Runtime &runtime) {
|
||||||
uiManagerBinding_->stopSurface(runtime, surfaceId);
|
uiManagerBinding_->stopSurface(runtime, surfaceId);
|
||||||
});
|
});
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Size Scheduler::measureSurface(
|
Size Scheduler::measureSurface(
|
||||||
|
|
Загрузка…
Ссылка в новой задаче