前言
项目中用到RN也有一段时间了, 从刚开始的懵懂到现在的熟能生巧,其实还是很长的,每次接触一个新的东西的时候,刚开始一定是比较痛苦的,不知道要如何下手,这里从js到Android原生去一步步解析React Native
是如何做到如此巧妙的通信的。希望能对你们有所帮助。
这里以我目前项目中用到的版本为例:
{
"react": "16.0.0-alpha.12",
"react-native": "^0.46.4",
}
JS
我们先从js端入手
import { AppRegistry } from 'react-native'
...省略代码
AppRegistry.registerComponent('xemall', () => Index)
上述代码就是JS程序的入口,将当前APP对象注册到AppRegistry
组件中,AppRegistry组件是js module。
启动流程
我们新建一个RN的项目,在原生代码中会生成MainActivity
和MainApplication
两个Java类。顾名思义,MainAcitivity
就是我们的Native的入口了,
我们先来看下MainApplication
都做了哪些操作:
public class MainApplication extends Application implements ReactApplication {
//ReactNativeHost:持有ReactInstanceManager实例,做一些初始化操作。
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
//SoLoader:加载C++底层库,准备解析JS。
SoLoader.init(this, /* native exopackage */ false);
}
}
}
我们再来看下MainActivity的代码:
public class MainActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "xemall";
}
}
可以看到其实是继承了ReactActivity
类,只是重写了getMainComponentName
方法,有没有看出来,其方法的返回值和我们在JS端的值是一样的。如果不一致会怎么样,你可以自己试一下。
ReactActivity
我们来看下ReactActivity
的方法的onCreate
方法:
public abstract class ReactActivity extends Activity
implements DefaultHardwareBackBtnHandler, PermissionAwareActivity {
private final ReactActivityDelegate mDelegate;
...省略代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDelegate.onCreate(savedInstanceState);
}
}
ReactActivity全权委托给ReactActivityDelegate
来处理。
ReactActivityDelegate
public class ReactActivityDelegate {
protected void onCreate(Bundle savedInstanceState) {
// 弹框权限判断
boolean needsOverlayPermission = false;
if (getReactNativeHost().getUseDeveloperSupport() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Get permission to show redbox in dev builds.
if (!Settings.canDrawOverlays(getContext())) {
needsOverlayPermission = true;
Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getContext().getPackageName()));
FLog.w(ReactConstants.TAG, REDBOX_PERMISSION_MESSAGE);
Toast.makeText(getContext(), REDBOX_PERMISSION_MESSAGE, Toast.LENGTH_LONG).show();
((Activity) getContext()).startActivityForResult(serviceIntent, REQUEST_OVERLAY_PERMISSION_CODE);
}
}
// 加载组建逻辑 mMainComponentName为getMainComponentName返回的值
if (mMainComponentName != null && !needsOverlayPermission) {
loadApp(mMainComponentName);
}
// 双击判断工具类
mDoubleTapReloadRecognizer = new DoubleTapReloadRecognizer();
}
protected void loadApp(String appKey) {
//空判断
if (mReactRootView != null) {
throw new IllegalStateException("Cannot loadApp while app is already running.");
}
// 创建 RN容器根视图
mReactRootView = createRootView();
mReactRootView.startReactApplication(