mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-08 17:22:05 +08:00
When addRootView() is called in a background thread, execute it as a generic UIOperation command in UIViewOperationQueue
Summary: public There is really no reason NativeViewHierarchyManager.addRootView() should be performed synchroniously when called from background thread, as long as it is executed before every other command in UIViewOperationQueue, and we can ensure that by putting add view command at the front of the queue. When that happpens, the queue should always be empty anyway, but it's best to be safe. This eliminates an unnecessary blocking call and should overall make the code simpler and safer (Semaphores can timeout). Reviewed By: astreet Differential Revision: D2462680 fb-gh-sync-id: 784ac6573a455019b93628c70992f3830b9d6f1f
This commit is contained in:
committed by
facebook-github-bot-5
parent
16350ae09b
commit
aeda31428d
@@ -14,8 +14,6 @@ import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
@@ -31,8 +29,6 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.SoftAssertions;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
@@ -75,7 +71,6 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
||||
// increment here is 10
|
||||
private static final int ROOT_VIEW_TAG_INCREMENT = 10;
|
||||
|
||||
private final NativeViewHierarchyManager mNativeViewHierarchyManager;
|
||||
private final EventDispatcher mEventDispatcher;
|
||||
private final ShadowNodeRegistry mShadowNodeRegistry = new ShadowNodeRegistry();
|
||||
private final ViewManagerRegistry mViewManagers;
|
||||
@@ -92,10 +87,9 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
||||
super(reactContext);
|
||||
mViewManagers = new ViewManagerRegistry(viewManagerList);
|
||||
mEventDispatcher = new EventDispatcher(reactContext);
|
||||
mNativeViewHierarchyManager = new NativeViewHierarchyManager(mViewManagers);
|
||||
mOperationsQueue = new UIViewOperationQueue(
|
||||
reactContext,
|
||||
mNativeViewHierarchyManager);
|
||||
new NativeViewHierarchyManager(mViewManagers));
|
||||
mNativeViewHierarchyOptimizer = new NativeViewHierarchyOptimizer(
|
||||
mOperationsQueue,
|
||||
mShadowNodeRegistry);
|
||||
@@ -197,26 +191,8 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
||||
|
||||
mShadowNodeRegistry.addRootNode(rootCSSNode);
|
||||
|
||||
if (UiThreadUtil.isOnUiThread()) {
|
||||
mNativeViewHierarchyManager.addRootView(tag, rootView, themedRootContext);
|
||||
} else {
|
||||
final Semaphore semaphore = new Semaphore(0);
|
||||
getReactApplicationContext().runOnUiQueueThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mNativeViewHierarchyManager.addRootView(tag, rootView, themedRootContext);
|
||||
semaphore.release();
|
||||
}
|
||||
});
|
||||
try {
|
||||
SoftAssertions.assertCondition(
|
||||
semaphore.tryAcquire(5000, TimeUnit.MILLISECONDS),
|
||||
"Timed out adding root view");
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
// register it within NativeViewHierarchyManager
|
||||
mOperationsQueue.addRootView(tag, rootView, themedRootContext);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@@ -13,13 +13,17 @@ import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.facebook.react.animation.Animation;
|
||||
import com.facebook.react.animation.AnimationRegistry;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.SoftAssertions;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
||||
import com.facebook.systrace.Systrace;
|
||||
import com.facebook.systrace.SystraceMessage;
|
||||
@@ -448,6 +452,7 @@ public class UIViewOperationQueue {
|
||||
|
||||
private final Object mDispatchRunnablesLock = new Object();
|
||||
private final DispatchUIFrameCallback mDispatchUIFrameCallback;
|
||||
private final ReactApplicationContext mReactApplicationContext;
|
||||
|
||||
@GuardedBy("mDispatchRunnablesLock")
|
||||
private final ArrayList<Runnable> mDispatchUIRunnables = new ArrayList<>();
|
||||
@@ -460,6 +465,7 @@ public class UIViewOperationQueue {
|
||||
mNativeViewHierarchyManager = nativeViewHierarchyManager;
|
||||
mAnimationRegistry = nativeViewHierarchyManager.getAnimationRegistry();
|
||||
mDispatchUIFrameCallback = new DispatchUIFrameCallback(reactContext);
|
||||
mReactApplicationContext = reactContext;
|
||||
}
|
||||
|
||||
public void setViewHierarchyUpdateDebugListener(
|
||||
@@ -471,6 +477,32 @@ public class UIViewOperationQueue {
|
||||
return mOperations.isEmpty();
|
||||
}
|
||||
|
||||
public void addRootView(
|
||||
final int tag,
|
||||
final SizeMonitoringFrameLayout rootView,
|
||||
final ThemedReactContext themedRootContext) {
|
||||
if (UiThreadUtil.isOnUiThread()) {
|
||||
mNativeViewHierarchyManager.addRootView(tag, rootView, themedRootContext);
|
||||
} else {
|
||||
final Semaphore semaphore = new Semaphore(0);
|
||||
mReactApplicationContext.runOnUiQueueThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mNativeViewHierarchyManager.addRootView(tag, rootView, themedRootContext);
|
||||
semaphore.release();
|
||||
}
|
||||
});
|
||||
try {
|
||||
SoftAssertions.assertCondition(
|
||||
semaphore.tryAcquire(5000, TimeUnit.MILLISECONDS),
|
||||
"Timed out adding root view");
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void enqueueRemoveRootView(int rootViewTag) {
|
||||
mOperations.add(new RemoveRootViewOperation(rootViewTag));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user