当前分析的ReactNative版本为0.61.5:
首先来看ReactRootView的定义:
/**
* Default root view for catalyst apps. Provides the ability to listen for size changes so that a UI
* manager can re-layout its elements. It delegates handling touch events for itself and child views
* and sending those events to JS by using JSTouchDispatcher. This view is overriding {@link
* ViewGroup#onInterceptTouchEvent} method in order to be notified about the events for all of its
* children and it's also overriding {@link ViewGroup#requestDisallowInterceptTouchEvent} to make
* sure that {@link ViewGroup#onInterceptTouchEvent} will get events even when some child view start
* intercepting it. In case when no child view is interested in handling some particular touch
* event, this view's {@link View#onTouchEvent} will still return true in order to be notified about
* all subsequent touch events related to that gesture (in case when JS code wants to handle that
* gesture).
*/
public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
}
通过定义 ,我们看到它本质上是一个 FrameLayout , 同时实现了RootView和ReactRoot接口。
先来看看ReactRoot提供的主要功能:
1.获取appProperties。react app启动时传入的参数;
2. 设置获取RootViewTag;
3. runApplication。这个是最终JS启动运行的入口;
4. onStage,这个后面再说;
一、ReactRootView加载流程
首先ReactRootVieiw本质是个FrameLayout,它的创建过程和一般的View 创建,初始化过程一样,看下它的onMeasure方法:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mUseSurface) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "ReactRootView.onMeasure");
try {
boolean measureSpecsUpdated =
widthMeasureSpec != mWidthMeasureSpec || heightMeasureSpec != mHeightMeasureSpec;
mWidthMeasureSpec = widthMeasureSpec;
mHeightMeasureSpec = heightMeasureSpec;
int width = 0;
int height = 0;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.UNSPECIFIED) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
int childSize =
child.getLeft()
+ child.getMeasuredWidth()
+ child.getPaddingLeft()
+ child.getPaddingRight();
width = Math.max(width, childSize);
}
} else {
width = MeasureSpec.getSize(widthMeasureSpec);
}
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED