Fix crash associated with setJSResponderHandler
Summary: In Fabric we're seeing setJSResponderHandler called during teardown of a surface, which causes a crash because the SurfaceId is no longer available at that point. Guard against setJSResponderHandler being called on a dead surface. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D26734786 fbshipit-source-id: 838d682ee0dd1d4de49993fa479dc2097cf33521
This commit is contained in:
Родитель
b08362ade5
Коммит
21a434ceec
|
@ -1079,8 +1079,15 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
|||
new MountItem() {
|
||||
@Override
|
||||
public void execute(MountingManager mountingManager) {
|
||||
mountingManager.setJSResponder(
|
||||
surfaceId, reactTag, initialReactTag, blockNativeResponder);
|
||||
SurfaceMountingManager surfaceMountingManager =
|
||||
mountingManager.getSurfaceManager(surfaceId);
|
||||
if (surfaceMountingManager != null) {
|
||||
surfaceMountingManager.setJSResponder(
|
||||
reactTag, initialReactTag, blockNativeResponder);
|
||||
} else {
|
||||
FLog.e(
|
||||
TAG, "setJSResponder skipped, surface no longer available [" + surfaceId + "]");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -270,38 +270,15 @@ public class MountingManager {
|
|||
getSurfaceManagerForViewEnforced(reactTag).updateProps(reactTag, props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the JS responder for the view associated with the tags received as a parameter.
|
||||
*
|
||||
* <p>The JSResponder coordinates the return values of the onInterceptTouch method in Android
|
||||
* Views. This allows JS to coordinate when a touch should be handled by JS or by the Android
|
||||
* native views. See {@link JSResponderHandler} for more details.
|
||||
*
|
||||
* <p>This method is going to be executed on the UIThread as soon as it is delivered from JS to
|
||||
* RN.
|
||||
*
|
||||
* <p>Currently, there is no warranty that the view associated with the react tag exists, because
|
||||
* this method is not handled by the react commit process.
|
||||
*
|
||||
* @param reactTag React tag of the first parent of the view that is NOT virtual
|
||||
* @param initialReactTag React tag of the JS view that initiated the touch operation
|
||||
* @param blockNativeResponder If native responder should be blocked or not
|
||||
*/
|
||||
@UiThread
|
||||
public synchronized void setJSResponder(
|
||||
int surfaceId, int reactTag, int initialReactTag, boolean blockNativeResponder) {
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
|
||||
getSurfaceManagerEnforced(surfaceId, "setJSResponder")
|
||||
.setJSResponder(reactTag, initialReactTag, blockNativeResponder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the JS Responder specified by {@link #setJSResponder(int, int, int, boolean)}. After
|
||||
* this method is called, all the touch events are going to be handled by JS.
|
||||
*/
|
||||
@UiThread
|
||||
public void clearJSResponder() {
|
||||
// MountingManager and SurfaceMountingManagers all share the same JSResponderHandler.
|
||||
// Must be called on MountingManager instead of SurfaceMountingManager, because we don't
|
||||
// know what surfaceId it's being called for.
|
||||
mJSResponderHandler.clearJSResponder();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import androidx.annotation.Nullable;
|
|||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
import com.facebook.react.fabric.mounting.SurfaceMountingManager;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
|
||||
/** {@link MountItem} that is used to pre-allocate views for JS components. */
|
||||
|
@ -53,9 +54,15 @@ public class PreAllocateViewMountItem implements MountItem {
|
|||
if (ENABLE_FABRIC_LOGS) {
|
||||
FLog.d(TAG, "Executing pre-allocation of: " + toString());
|
||||
}
|
||||
mountingManager
|
||||
.getSurfaceManagerEnforced(mSurfaceId, "PreAllocateViewMountItem")
|
||||
.preallocateView(mComponent, mReactTag, mProps, mStateWrapper, mIsLayoutable);
|
||||
SurfaceMountingManager surfaceMountingManager = mountingManager.getSurfaceManager(mSurfaceId);
|
||||
if (surfaceMountingManager == null) {
|
||||
FLog.e(
|
||||
TAG,
|
||||
"Skipping View PreAllocation; no SurfaceMountingManager found for [" + mSurfaceId + "]");
|
||||
return;
|
||||
}
|
||||
surfaceMountingManager.preallocateView(
|
||||
mComponent, mReactTag, mProps, mStateWrapper, mIsLayoutable);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Загрузка…
Ссылка в новой задаче