mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-30 05:55:48 +08:00
Refactor setup of Event Dispatcher
Reviewed By: achen1 Differential Revision: D7746311 fbshipit-source-id: cfee1c2ced6d85477628085f3260496e80ae48c2
This commit is contained in:
committed by
Facebook Github Bot
parent
e61341ba32
commit
58ea20b5e8
@@ -7,11 +7,12 @@
|
|||||||
|
|
||||||
package com.facebook.react.testing;
|
package com.facebook.react.testing;
|
||||||
|
|
||||||
|
import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.FragmentActivity;
|
import android.support.v4.app.FragmentActivity;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
@@ -38,7 +39,7 @@ import com.facebook.react.testing.idledetection.ReactIdleDetectionUtil;
|
|||||||
import com.facebook.react.uimanager.UIImplementationProvider;
|
import com.facebook.react.uimanager.UIImplementationProvider;
|
||||||
import com.facebook.react.uimanager.ViewManager;
|
import com.facebook.react.uimanager.ViewManager;
|
||||||
import com.facebook.react.uimanager.ViewManagerRegistry;
|
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||||
import java.util.ArrayList;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -244,35 +245,28 @@ public class ReactAppTestActivity extends FragmentActivity
|
|||||||
.setBridgeIdleDebugListener(mBridgeIdleSignaler)
|
.setBridgeIdleDebugListener(mBridgeIdleSignaler)
|
||||||
.setInitialLifecycleState(mLifecycleState)
|
.setInitialLifecycleState(mLifecycleState)
|
||||||
.setJSIModulesProvider(
|
.setJSIModulesProvider(
|
||||||
new JSIModulesProvider() {
|
new JSIModulesProvider() {
|
||||||
@Override
|
@Override
|
||||||
public List<JSIModuleHolder> getJSIModules(
|
public List<JSIModuleHolder> getJSIModules(
|
||||||
final ReactApplicationContext reactApplicationContext,
|
final ReactApplicationContext reactApplicationContext,
|
||||||
final JavaScriptContextHolder jsContext) {
|
final JavaScriptContextHolder jsContext) {
|
||||||
|
return Arrays.<JSIModuleHolder>asList(new JSIModuleHolder() {
|
||||||
|
@Override
|
||||||
|
public Class<? extends JSIModule> getJSIModuleClass() {
|
||||||
|
return UIManager.class;
|
||||||
|
}
|
||||||
|
|
||||||
List<JSIModuleHolder> modules = new ArrayList<>();
|
@Override
|
||||||
modules.add(
|
public FabricUIManager getJSIModule() {
|
||||||
new JSIModuleHolder() {
|
List<ViewManager> viewManagers =
|
||||||
|
mReactInstanceManager.getOrCreateViewManagers(reactApplicationContext);
|
||||||
@Override
|
FabricUIManager fabricUIManager =
|
||||||
public Class<? extends JSIModule> getJSIModuleClass() {
|
new FabricUIManager(reactApplicationContext, new ViewManagerRegistry(viewManagers));
|
||||||
return UIManager.class;
|
new FabricJSCBinding().installFabric(jsContext, fabricUIManager);
|
||||||
}
|
return fabricUIManager;
|
||||||
|
}
|
||||||
@Override
|
});
|
||||||
public FabricUIManager getJSIModule() {
|
}})
|
||||||
List<ViewManager> viewManagers =
|
|
||||||
getReactInstanceManager().getOrCreateViewManagers(reactApplicationContext);
|
|
||||||
FabricUIManager fabricUIManager =
|
|
||||||
new FabricUIManager(
|
|
||||||
reactApplicationContext, new ViewManagerRegistry(viewManagers));
|
|
||||||
new FabricJSCBinding().installFabric(jsContext, fabricUIManager);
|
|
||||||
return fabricUIManager;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return modules;
|
|
||||||
}})
|
|
||||||
.setUIImplementationProvider(uiImplementationProvider);
|
.setUIImplementationProvider(uiImplementationProvider);
|
||||||
|
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ import com.facebook.react.uimanager.DisplayMetricsHolder;
|
|||||||
import com.facebook.react.uimanager.UIImplementationProvider;
|
import com.facebook.react.uimanager.UIImplementationProvider;
|
||||||
import com.facebook.react.uimanager.UIManagerHelper;
|
import com.facebook.react.uimanager.UIManagerHelper;
|
||||||
import com.facebook.react.uimanager.ViewManager;
|
import com.facebook.react.uimanager.ViewManager;
|
||||||
|
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||||
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
|
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
|
||||||
import com.facebook.soloader.SoLoader;
|
import com.facebook.soloader.SoLoader;
|
||||||
import com.facebook.systrace.Systrace;
|
import com.facebook.systrace.Systrace;
|
||||||
@@ -1077,6 +1078,8 @@ public class ReactInstanceManager {
|
|||||||
ReactMarker.logMarker(CREATE_REACT_CONTEXT_START, jsExecutor.getName());
|
ReactMarker.logMarker(CREATE_REACT_CONTEXT_START, jsExecutor.getName());
|
||||||
final ReactApplicationContext reactContext = new ReactApplicationContext(mApplicationContext);
|
final ReactApplicationContext reactContext = new ReactApplicationContext(mApplicationContext);
|
||||||
|
|
||||||
|
reactContext.setEventDispatcher(new EventDispatcher(reactContext));
|
||||||
|
|
||||||
NativeModuleCallExceptionHandler exceptionHandler = mNativeModuleCallExceptionHandler != null
|
NativeModuleCallExceptionHandler exceptionHandler = mNativeModuleCallExceptionHandler != null
|
||||||
? mNativeModuleCallExceptionHandler
|
? mNativeModuleCallExceptionHandler
|
||||||
: mDevSupportManager;
|
: mDevSupportManager;
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* 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.bridge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marker interface for EventDispatcher.
|
||||||
|
*/
|
||||||
|
public interface EventDispatcher {
|
||||||
|
}
|
||||||
@@ -39,6 +39,7 @@ public class ReactContext extends ContextWrapper {
|
|||||||
|
|
||||||
private LifecycleState mLifecycleState = LifecycleState.BEFORE_CREATE;
|
private LifecycleState mLifecycleState = LifecycleState.BEFORE_CREATE;
|
||||||
|
|
||||||
|
private @Nullable EventDispatcher mEventDispatcher;
|
||||||
private @Nullable CatalystInstance mCatalystInstance;
|
private @Nullable CatalystInstance mCatalystInstance;
|
||||||
private @Nullable LayoutInflater mInflater;
|
private @Nullable LayoutInflater mInflater;
|
||||||
private @Nullable MessageQueueThread mUiMessageQueueThread;
|
private @Nullable MessageQueueThread mUiMessageQueueThread;
|
||||||
@@ -349,4 +350,12 @@ public class ReactContext extends ContextWrapper {
|
|||||||
public JavaScriptContextHolder getJavaScriptContextHolder() {
|
public JavaScriptContextHolder getJavaScriptContextHolder() {
|
||||||
return mCatalystInstance.getJavaScriptContextHolder();
|
return mCatalystInstance.getJavaScriptContextHolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T extends EventDispatcher> T getEventDispatcher() {
|
||||||
|
return (T) mEventDispatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventDispatcher(EventDispatcher eventDispatcher) {
|
||||||
|
mEventDispatcher = eventDispatcher;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public class Scheduler {
|
|||||||
public void scheduleWork(Work work) {
|
public void scheduleWork(Work work) {
|
||||||
// TODO T26717866 this method needs to be implemented. The current implementation is just for
|
// TODO T26717866 this method needs to be implemented. The current implementation is just for
|
||||||
// testing purpose.
|
// testing purpose.
|
||||||
|
|
||||||
work.run();
|
work.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,11 @@ package com.facebook.react.uimanager;
|
|||||||
|
|
||||||
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_CONSTANTS_END;
|
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_CONSTANTS_END;
|
||||||
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_CONSTANTS_START;
|
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_CONSTANTS_START;
|
||||||
|
|
||||||
import static com.facebook.react.uimanager.common.UIManagerType.DEFAULT;
|
import static com.facebook.react.uimanager.common.UIManagerType.DEFAULT;
|
||||||
|
|
||||||
import android.content.ComponentCallbacks2;
|
import android.content.ComponentCallbacks2;
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import com.facebook.common.logging.FLog;
|
import com.facebook.common.logging.FLog;
|
||||||
import com.facebook.debug.holder.PrinterHolder;
|
import com.facebook.debug.holder.PrinterHolder;
|
||||||
@@ -42,6 +41,7 @@ import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
|
|||||||
import com.facebook.react.uimanager.common.ViewUtil;
|
import com.facebook.react.uimanager.common.ViewUtil;
|
||||||
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
||||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||||
|
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||||
import com.facebook.systrace.Systrace;
|
import com.facebook.systrace.Systrace;
|
||||||
import com.facebook.systrace.SystraceMessage;
|
import com.facebook.systrace.SystraceMessage;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -129,7 +129,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
|||||||
int minTimeLeftInFrameForNonBatchedOperationMs) {
|
int minTimeLeftInFrameForNonBatchedOperationMs) {
|
||||||
super(reactContext);
|
super(reactContext);
|
||||||
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext);
|
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext);
|
||||||
mEventDispatcher = new EventDispatcher(reactContext);
|
mEventDispatcher = reactContext.getEventDispatcher();
|
||||||
mModuleConstants = createConstants(viewManagerResolver);
|
mModuleConstants = createConstants(viewManagerResolver);
|
||||||
mCustomDirectEvents = UIManagerModuleConstants.getDirectEventTypeConstants();
|
mCustomDirectEvents = UIManagerModuleConstants.getDirectEventTypeConstants();
|
||||||
mUIImplementation =
|
mUIImplementation =
|
||||||
@@ -149,7 +149,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
|||||||
int minTimeLeftInFrameForNonBatchedOperationMs) {
|
int minTimeLeftInFrameForNonBatchedOperationMs) {
|
||||||
super(reactContext);
|
super(reactContext);
|
||||||
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext);
|
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext);
|
||||||
mEventDispatcher = new EventDispatcher(reactContext);
|
mEventDispatcher = reactContext.getEventDispatcher();
|
||||||
mCustomDirectEvents = MapBuilder.newHashMap();
|
mCustomDirectEvents = MapBuilder.newHashMap();
|
||||||
mModuleConstants = createConstants(viewManagersList, null, mCustomDirectEvents);
|
mModuleConstants = createConstants(viewManagersList, null, mCustomDirectEvents);
|
||||||
mUIImplementation =
|
mUIImplementation =
|
||||||
@@ -182,10 +182,14 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
|||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
getReactApplicationContext().registerComponentCallbacks(mMemoryTrimCallback);
|
getReactApplicationContext().registerComponentCallbacks(mMemoryTrimCallback);
|
||||||
|
mEventDispatcher.registerEventEmitter(
|
||||||
|
DEFAULT,
|
||||||
|
getReactApplicationContext().getJSModule(RCTEventEmitter.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHostResume() {
|
public void onHostResume() {
|
||||||
|
|
||||||
mUIImplementation.onHostResume();
|
mUIImplementation.onHostResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,16 +7,7 @@
|
|||||||
|
|
||||||
package com.facebook.react.uimanager.events;
|
package com.facebook.react.uimanager.events;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
import android.util.LongSparseArray;
|
import android.util.LongSparseArray;
|
||||||
|
|
||||||
import com.facebook.infer.annotation.Assertions;
|
import com.facebook.infer.annotation.Assertions;
|
||||||
import com.facebook.react.bridge.LifecycleEventListener;
|
import com.facebook.react.bridge.LifecycleEventListener;
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
@@ -26,6 +17,12 @@ import com.facebook.react.modules.core.ChoreographerCompat;
|
|||||||
import com.facebook.react.modules.core.ReactChoreographer;
|
import com.facebook.react.modules.core.ReactChoreographer;
|
||||||
import com.facebook.react.uimanager.common.UIManagerType;
|
import com.facebook.react.uimanager.common.UIManagerType;
|
||||||
import com.facebook.systrace.Systrace;
|
import com.facebook.systrace.Systrace;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class responsible for dispatching UI events to JS. The main purpose of this class is to act as an
|
* Class responsible for dispatching UI events to JS. The main purpose of this class is to act as an
|
||||||
@@ -59,7 +56,8 @@ import com.facebook.systrace.Systrace;
|
|||||||
* EVENT_TYPE_ID_MASK = 0x0000ffff00000000
|
* EVENT_TYPE_ID_MASK = 0x0000ffff00000000
|
||||||
* COALESCING_KEY_MASK = 0xffff000000000000
|
* COALESCING_KEY_MASK = 0xffff000000000000
|
||||||
*/
|
*/
|
||||||
public class EventDispatcher implements LifecycleEventListener {
|
public class EventDispatcher implements LifecycleEventListener,
|
||||||
|
com.facebook.react.bridge.EventDispatcher {
|
||||||
|
|
||||||
private static final Comparator<Event> EVENT_COMPARATOR = new Comparator<Event>() {
|
private static final Comparator<Event> EVENT_COMPARATOR = new Comparator<Event>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -99,7 +97,7 @@ public class EventDispatcher implements LifecycleEventListener {
|
|||||||
|
|
||||||
private Event[] mEventsToDispatch = new Event[16];
|
private Event[] mEventsToDispatch = new Event[16];
|
||||||
private int mEventsToDispatchSize = 0;
|
private int mEventsToDispatchSize = 0;
|
||||||
private volatile @Nullable RCTEventEmitter mRCTEventEmitter;
|
private volatile @Nullable ReactEventEmitter mRCTEventEmitter = new ReactEventEmitter();
|
||||||
private short mNextEventTypeId = 0;
|
private short mNextEventTypeId = 0;
|
||||||
private volatile boolean mHasDispatchScheduled = false;
|
private volatile boolean mHasDispatchScheduled = false;
|
||||||
|
|
||||||
@@ -153,9 +151,6 @@ public class EventDispatcher implements LifecycleEventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHostResume() {
|
public void onHostResume() {
|
||||||
if (mRCTEventEmitter == null) {
|
|
||||||
mRCTEventEmitter = mReactContext.getJSModule(RCTEventEmitter.class);
|
|
||||||
}
|
|
||||||
mCurrentFrameCallback.maybePostFromNonUI();
|
mCurrentFrameCallback.maybePostFromNonUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,6 +250,10 @@ public class EventDispatcher implements LifecycleEventListener {
|
|||||||
(((long) coalescingKey) & 0xffff) << 48;
|
(((long) coalescingKey) & 0xffff) << 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void registerEventEmitter(@UIManagerType int uiManagerType, RCTEventEmitter eventEmitter) {
|
||||||
|
mRCTEventEmitter.register(uiManagerType, eventEmitter);
|
||||||
|
}
|
||||||
|
|
||||||
private class ScheduleDispatchFrameCallback extends ChoreographerCompat.FrameCallback {
|
private class ScheduleDispatchFrameCallback extends ChoreographerCompat.FrameCallback {
|
||||||
private volatile boolean mIsPosted = false;
|
private volatile boolean mIsPosted = false;
|
||||||
private boolean mShouldStop = false;
|
private boolean mShouldStop = false;
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import com.facebook.react.bridge.WritableArray;
|
|||||||
import com.facebook.react.bridge.WritableMap;
|
import com.facebook.react.bridge.WritableMap;
|
||||||
|
|
||||||
public interface RCTEventEmitter extends JavaScriptModule {
|
public interface RCTEventEmitter extends JavaScriptModule {
|
||||||
public void receiveEvent(int targetTag, String eventName, @Nullable WritableMap event);
|
void receiveEvent(int targetTag, String eventName, @Nullable WritableMap event);
|
||||||
public void receiveTouches(
|
void receiveTouches(
|
||||||
String eventName,
|
String eventName,
|
||||||
WritableArray touches,
|
WritableArray touches,
|
||||||
WritableArray changedIndices);
|
WritableArray changedIndices);
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* 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.uimanager.events;
|
||||||
|
|
||||||
|
import static com.facebook.react.uimanager.events.TouchesHelper.TARGET_KEY;
|
||||||
|
|
||||||
|
import android.util.SparseArray;
|
||||||
|
import com.facebook.infer.annotation.Assertions;
|
||||||
|
import com.facebook.react.bridge.WritableArray;
|
||||||
|
import com.facebook.react.bridge.WritableMap;
|
||||||
|
import com.facebook.react.uimanager.common.UIManagerType;
|
||||||
|
import com.facebook.react.uimanager.common.ViewUtil;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class ReactEventEmitter implements RCTEventEmitter {
|
||||||
|
|
||||||
|
private final SparseArray<RCTEventEmitter> mEventEmitters = new SparseArray<>();
|
||||||
|
|
||||||
|
public ReactEventEmitter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(@UIManagerType int uiManagerType, RCTEventEmitter eventEmitter) {
|
||||||
|
mEventEmitters.put(uiManagerType, eventEmitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receiveEvent(int targetReactTag, String eventName, @Nullable WritableMap event) {
|
||||||
|
getEventEmitter(targetReactTag).receiveEvent(targetReactTag, eventName, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receiveTouches(
|
||||||
|
String eventName,
|
||||||
|
WritableArray touches,
|
||||||
|
WritableArray changedIndices) {
|
||||||
|
|
||||||
|
Assertions.assertCondition(touches.size() > 0);
|
||||||
|
|
||||||
|
int targetReactTag = touches.getMap(0).getInt(TARGET_KEY);
|
||||||
|
getEventEmitter(targetReactTag).receiveTouches(eventName, touches, changedIndices);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RCTEventEmitter getEventEmitter(int reactTag) {
|
||||||
|
int type = ViewUtil.getUIManagerType(reactTag);
|
||||||
|
return mEventEmitters.get(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user