Detailed analysis of React Native startup process
- 2021-11-13 00:22:39
- OfStack
Introduction: This article is based on
react-native-cli
The example project created (Android part) is taken as an example to analyze the startup process of React Native.
Please refer to official website for project creation steps. The analysis of this paper
React Native
Version is
v0.64.2
.
We know that the above project is an Android application, open it
android/
Directory source code files, first found that it created two java files:
MainApplication.java
And
MainActivity.java
The application and main Activity are defined respectively.
The startup process of Android application is as follows: After starting the first
activity
A globally only 1 is created before
Application
Object. Therefore, here we first analyze
MainApplication
MainApplication
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Other pairs packages Operation of
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
}
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
MainApplication
Inherits from the Application class and implements the
React Native
0
Interface. Among the things done are:
1. Create member variables
React Native
1
And inject 1 configuration during creation by overriding the ReactNativeHost class method, including:
2. In onCreate:
Call the Soloader library.React Native
2
Is an so file loading library introduced by facebook, which can handle the dependency of so files. In react-native, all framework-related so files are loaded through SoLoader
Pass
React Native
3
Initialize Flipper.
React Native
4
It is a tool introduced by facebook for debug ios, Android, React Native applications.
Here is a brief introduction
React Native
1
And
React Native
3
ReactNativeHost
React Native
1
Is an abstract class, and developers can override the methods in it. Its main function is to specify 1 assignment operation in application, and then get
React Native
3
Gets or sets an instance of the. So you can put
React Native
1
As a way to assign user-defined parameters to
React Native
3
The staging station for the instance. The core approach is:
v0.64.2
1
For a detailed analysis, see below.
ReactInstanceManager
This class is the core class, which is mainly responsible for managing the loading of JS, maintaining the life cycle, managing the interaction between JS and C + +, and so on. You can put
React Native
3
It is understood as the transit bridge between JS and C + +.
MainActivity
Keep looking
MainActivity.java
:
public class MainActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "myProject";
}
}
v0.64.2
4
Only the getMainComponentName method is overridden in the. This class inherits from
v0.64.2
5
Let's look at it again
v0.64.2
5
.
public abstract class ReactActivity extends AppCompatActivity
implements DefaultHardwareBackBtnHandler, PermissionAwareActivity {
private final ReactActivityDelegate mDelegate;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDelegate.onCreate(savedInstanceState);
}
v0.64.2
5
Entrust with full authority
v0.64.2
8
To deal with
v0.64.2
9
Life cycle. Come and see
v0.64.2
8
Adj.
v0.64.2
9
.
protected void onCreate(Bundle savedInstanceState) {
String mainComponentName = getMainComponentName();
mReactDelegate =
new ReactDelegate(
getPlainActivity(), getReactNativeHost(), mainComponentName, getLaunchOptions()) {
@Override
protected ReactRootView createRootView() {
return ReactActivityDelegate.this.createRootView();
}
};
if (mMainComponentName != null) {
loadApp(mainComponentName);
}
}
The ReactDelegate instance is first created here. Let's take a look
android/
2
Methods:
protected void loadApp(String appKey) {
mReactDelegate.loadApp(appKey);
getPlainActivity().setContentView(mReactDelegate.getReactRootView());
}
From this to
ReactDelegate
Instance of the
android/
2
Methods:
public void loadApp(String appKey) {
if (mReactRootView != null) {
throw new IllegalStateException("Cannot loadApp while app is already running.");
}
mReactRootView = createRootView();
mReactRootView.startReactApplication(
getReactNativeHost().getReactInstanceManager(), appKey, mLaunchOptions);
}
Three things are done here: Create rootView (
createRootView
), creating ReactInstanceManager (
v0.64.2
1
), creating ReactApplication (
startReactApplication
).
createRootView
First, look at what rootView is.
public class ReactRootView extends FrameLayout implements RootView, ReactRoot { /* ... */}
ReactRootView inherits from
FrameLayout
And implements the
RootView
,
ReactRoot
Two interfaces.
FrameLayout
It is one of the simpler layouts of Android. The whole interface is regarded as a blank spare area, and all elements are aligned and stacked in the upper left corner. ReactRootView inherits from
FrameLayout
Which indicates that it also exists as a simple layout,
UI 的绘制渲染
It all happened up there.
getReactInstanceManager
React Native
3
Is a core class, which manages the loading of JS, the interaction between C + + and JS, initialization parameters, etc. The final call comes
React Native
1
Class in the
createReactInstanceManager
Methods:
protected ReactInstanceManager createReactInstanceManager() {
ReactInstanceManagerBuilder builder = /* ... */
for (ReactPackage reactPackage : getPackages()) {
builder.addPackage(reactPackage);
}
String jsBundleFile = getJSBundleFile();
if (jsBundleFile != null) {
builder.setJSBundleFile(jsBundleFile);
} else {
builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName()));
}
ReactInstanceManager reactInstanceManager = builder.build();
return reactInstanceManager;
}
The things done here are as follows:
CreateReactInstanceManagerBuilder
Instance. Here, the builder mode is used to construct
React Native
3
Instance, so pass the parameter setting constructor here first;
Put in
React Native
1
Registered in
MainActivity.java
0
Add to
ReactInstanceManagerBuilder
Instance;
If
MainActivity.java
2
Is not empty, the corresponding file is loaded; Otherwise, the default
MainActivity.java
3
;
Call
MainActivity.java
4
Method. Through the real construction of the builder
React Native
3
Instances
startReactApplication
public void startReactApplication(/* */) {
// ...
try {
// ...
mReactInstanceManager.createReactContextInBackground();
} finally {
// ...
}
}
Final execution to
React Native
3
Adj.
MainActivity.java
7
Method. Finally, through the call chain:
MainActivity.java
8
MainActivity.java
9
I mainly did two things:
activity
0
Create
activity
1
Context;
Pass
activity
2
To set the context, and finally call the
activity
3
Start App.
Detailed analysis is put into another article: React Native startReactApplication process combing.
Summarize
Summarize this article and pass
react-native-cli
Create a sample project (Android part) as an example, following two classes
MainApplication
And
v0.64.2
4
The execution process, grasping the backbone logic, and finally combing out
React Native
From Start to Execute User
activity
8
File process. You can see:
MainApplication
The main function is to pass in the user configuration and do
Application
0
Libraries and Applications
Application
1
Initialization of tools;
v0.64.2
4
The main functions are:
rootView
Layout container;
Create
React Native
3
Core class, which is used to manage the loading of JS, the interaction between C + + and JS, initialization parameters, etc.;
Pass
startReactApplication
To create
activity
1
Context, and eventually calls the
activity
3
Start App.