Implement release of FabricUIManager resources

Reviewed By: achen1

Differential Revision: D8232155

fbshipit-source-id: 6683c692a830f5a73aab2c606167e54d668ae5c2
This commit is contained in:
David Vacca 2018-06-01 17:47:46 -07:00 committed by Facebook Github Bot
parent 6aea98441a
commit 8529b1ee91
8 changed files with 59 additions and 8 deletions

View File

@ -30,6 +30,11 @@ public class ReactBridgeIdleSignaler implements NotThreadSafeBridgeIdleDebugList
mBridgeIdleSemaphore.release(); mBridgeIdleSemaphore.release();
} }
@Override
public void onBridgeDestroyed() {
// Do nothing
}
@Override @Override
public void onTransitionToBridgeBusy() { public void onTransitionToBridgeBusy() {
mIsBridgeIdle = false; mIsBridgeIdle = false;

View File

@ -338,10 +338,14 @@ public class CatalystInstanceImpl implements CatalystInstance {
@Override @Override
public void run() { public void run() {
mNativeModuleRegistry.notifyJSInstanceDestroy(); mNativeModuleRegistry.notifyJSInstanceDestroy();
mJSIModuleRegistry.notifyJSInstanceDestroy();
boolean wasIdle = (mPendingJSCalls.getAndSet(0) == 0); boolean wasIdle = (mPendingJSCalls.getAndSet(0) == 0);
if (!wasIdle && !mBridgeIdleListeners.isEmpty()) { if (!mBridgeIdleListeners.isEmpty()) {
for (NotThreadSafeBridgeIdleDebugListener listener : mBridgeIdleListeners) { for (NotThreadSafeBridgeIdleDebugListener listener : mBridgeIdleListeners) {
listener.onTransitionToBridgeIdle(); if (!wasIdle) {
listener.onTransitionToBridgeIdle();
}
listener.onBridgeDestroyed();
} }
} }
AsyncTask.execute( AsyncTask.execute(
@ -351,7 +355,8 @@ public class CatalystInstanceImpl implements CatalystInstance {
// Kill non-UI threads from neutral third party // Kill non-UI threads from neutral third party
// potentially expensive, so don't run on UI thread // potentially expensive, so don't run on UI thread
// contextHolder is used as a lock to guard against other users of the JS VM having // contextHolder is used as a lock to guard against other users of the JS VM
// having
// the VM destroyed underneath them, so notify them before we resetNative // the VM destroyed underneath them, so notify them before we resetNative
mJavaScriptContextHolder.clear(); mJavaScriptContextHolder.clear();

View File

@ -4,4 +4,16 @@ package com.facebook.react.bridge;
* Marker interface used to represent a JSI Module. * Marker interface used to represent a JSI Module.
*/ */
public interface JSIModule { public interface JSIModule {
/**
* This is called at the end of {@link CatalystApplicationFragment#createCatalystInstance()}
* after the CatalystInstance has been created, in order to initialize NativeModules that require
* the CatalystInstance or JS modules.
*/
void initialize();
/**
* Called before {CatalystInstance#onHostDestroy}
*/
void onCatalystInstanceDestroy();
} }

View File

@ -16,8 +16,15 @@ public class JSIModuleHolder {
return mModule; return mModule;
} }
mModule = mSpec.getJSIModuleProvider().get(); mModule = mSpec.getJSIModuleProvider().get();
mModule.initialize();
} }
} }
return mModule; return mModule;
} }
public void notifyJSInstanceDestroy() {
if (mModule != null) {
mModule.onCatalystInstanceDestroy();
}
}
} }

View File

@ -25,4 +25,9 @@ public class JSIModuleRegistry {
} }
} }
public void notifyJSInstanceDestroy() {
for (JSIModuleHolder moduleHolder : mModules.values()) {
moduleHolder.notifyJSInstanceDestroy();
}
}
} }

View File

@ -28,4 +28,9 @@ public interface NotThreadSafeBridgeIdleDebugListener {
* Called when the bridge was in an idle state and executes a JS call or callback. * Called when the bridge was in an idle state and executes a JS call or callback.
*/ */
void onTransitionToBridgeBusy(); void onTransitionToBridgeBusy();
/**
* Called when the bridge is destroyed
*/
void onBridgeDestroyed();
} }

View File

@ -29,7 +29,6 @@ import com.facebook.react.fabric.events.FabricEventEmitter;
import com.facebook.react.modules.i18nmanager.I18nUtil; import com.facebook.react.modules.i18nmanager.I18nUtil;
import com.facebook.react.uimanager.DisplayMetricsHolder; import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.NativeViewHierarchyManager; import com.facebook.react.uimanager.NativeViewHierarchyManager;
import com.facebook.react.uimanager.OnLayoutEvent;
import com.facebook.react.uimanager.ReactRootViewTagGenerator; import com.facebook.react.uimanager.ReactRootViewTagGenerator;
import com.facebook.react.uimanager.ReactShadowNode; import com.facebook.react.uimanager.ReactShadowNode;
import com.facebook.react.uimanager.ReactShadowNodeImpl; import com.facebook.react.uimanager.ReactShadowNodeImpl;
@ -84,10 +83,6 @@ public class FabricUIManager implements UIManager, JSHandler {
mFabricReconciler = new FabricReconciler(mUIViewOperationQueue); mFabricReconciler = new FabricReconciler(mUIViewOperationQueue);
mEventDispatcher = eventDispatcher; mEventDispatcher = eventDispatcher;
mJSContext = jsContext; mJSContext = jsContext;
FabricEventEmitter eventEmitter =
new FabricEventEmitter(reactContext, this);
eventDispatcher.registerEventEmitter(FABRIC, eventEmitter);
} }
public void setBinding(FabricBinding binding) { public void setBinding(FabricBinding binding) {
@ -538,4 +533,16 @@ public class FabricUIManager implements UIManager, JSHandler {
mBinding.dispatchEventToTarget(mJSContext.get(), mEventHandlerPointer, eventTarget, name, (WritableNativeMap) params); mBinding.dispatchEventToTarget(mJSContext.get(), mEventHandlerPointer, eventTarget, name, (WritableNativeMap) params);
} }
@Override
public void initialize() {
FabricEventEmitter eventEmitter =
new FabricEventEmitter(mReactApplicationContext, this);
mEventDispatcher.registerEventEmitter(FABRIC, eventEmitter);
}
@Override
public void onCatalystInstanceDestroy() {
mBinding.releaseEventHandler(mJSContext.get(), mEventHandlerPointer);
}
} }

View File

@ -42,6 +42,11 @@ public class DidJSUpdateUiDuringFrameDetector implements NotThreadSafeBridgeIdle
mTransitionToBusyEvents.add(System.nanoTime()); mTransitionToBusyEvents.add(System.nanoTime());
} }
@Override
public synchronized void onBridgeDestroyed() {
// do nothing
}
@Override @Override
public synchronized void onViewHierarchyUpdateEnqueued() { public synchronized void onViewHierarchyUpdateEnqueued() {
mViewHierarchyUpdateEnqueuedEvents.add(System.nanoTime()); mViewHierarchyUpdateEnqueuedEvents.add(System.nanoTime());