mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Summary: iOS will need to be implemented separately, but the shared C++ bits are in place. Explanation: there is currently no way for the View layer to /know/ if an UpdateState call has succeeded or failed. Generally we just assume it succeeds, but if it fails we have no way of knowing or retrying. This can cause some UI bugs. To mitigate this, I'm introducing a "failure" notification callback mechanism. The JNI bridging for this is a little complicated to avoid passing Runnable across the JNI, but it should be much simpler on iOS. In development this seems to make View components much more reliable. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D22940187 fbshipit-source-id: 917f2932ae22d421f91fe8f4fca3f07dc089f820
79 lines
2.3 KiB
Java
79 lines
2.3 KiB
Java
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
package com.facebook.react.fabric;
|
|
|
|
import android.annotation.SuppressLint;
|
|
import androidx.annotation.AnyThread;
|
|
import androidx.annotation.NonNull;
|
|
import com.facebook.jni.HybridData;
|
|
import com.facebook.proguard.annotations.DoNotStrip;
|
|
import com.facebook.react.bridge.NativeMap;
|
|
import com.facebook.react.bridge.ReadableNativeMap;
|
|
import com.facebook.react.bridge.UiThreadUtil;
|
|
import com.facebook.react.bridge.WritableMap;
|
|
import com.facebook.react.uimanager.StateWrapper;
|
|
|
|
/**
|
|
* This class holds reference to the C++ EventEmitter object. Instances of this class are created on
|
|
* the Bindings.cpp, where the pointer to the C++ event emitter is set.
|
|
*/
|
|
@SuppressLint("MissingNativeLoadLibrary")
|
|
public class StateWrapperImpl implements StateWrapper {
|
|
static {
|
|
FabricSoLoader.staticInit();
|
|
}
|
|
|
|
@DoNotStrip private final HybridData mHybridData;
|
|
|
|
private Runnable mFailureCallback = null;
|
|
private int mUpdateStateId = 0;
|
|
|
|
private static native HybridData initHybrid();
|
|
|
|
private StateWrapperImpl() {
|
|
mHybridData = initHybrid();
|
|
}
|
|
|
|
@Override
|
|
public native ReadableNativeMap getState();
|
|
|
|
public native void updateStateImpl(@NonNull NativeMap map);
|
|
|
|
public native void updateStateWithFailureCallbackImpl(
|
|
@NonNull NativeMap map, Object self, int updateStateId);
|
|
|
|
@Override
|
|
public void updateState(@NonNull WritableMap map) {
|
|
mUpdateStateId++;
|
|
updateStateImpl((NativeMap) map);
|
|
}
|
|
|
|
@Override
|
|
public void updateState(@NonNull WritableMap map, Runnable failureCallback) {
|
|
mUpdateStateId++;
|
|
mFailureCallback = failureCallback;
|
|
updateStateWithFailureCallbackImpl((NativeMap) map, this, mUpdateStateId);
|
|
}
|
|
|
|
@DoNotStrip
|
|
@AnyThread
|
|
public void updateStateFailed(int callbackRefId) {
|
|
// If the callback ref ID doesn't match the ID of the most-recent updateState call,
|
|
// then it's an outdated failure callback and we ignore it.
|
|
if (callbackRefId != mUpdateStateId) {
|
|
return;
|
|
}
|
|
|
|
final Runnable failureCallback = mFailureCallback;
|
|
mFailureCallback = null;
|
|
if (failureCallback != null) {
|
|
UiThreadUtil.runOnUiThread(failureCallback);
|
|
}
|
|
}
|
|
}
|