上一篇文章写了如何配置RN和Android原生混合开发的相关配置
Android 模块引入ReactNative相关环境配置
下面整理一下如何在原声项目中加载一个RN的页面,主要是加载一个bundle文件
1.使用RN生成bundle文件
首先在RN的android项目下新建assets文件夹,project结构下右击main文件夹,新建一个名字为assets的文件夹
2.生成bundle文件
使用配置好的node和RN环境,在命令行输入:
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res
在刚刚新建的assets中生成一个bundle文件,这个文件就是我们自己原生项目加载RN页面所需要的
3.*生成加载RN页面相关代码
public class MyReactActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler{
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
//index.android.bundle为assets中生成bundle文件的名字
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
//
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
// 注意这里的HelloWorld必须对应“index.android.js”中的
// “AppRegistry.registerComponent()”的第一个参数
mReactRootView.startReactApplication(mReactInstanceManager, "HelloWorld", null);
setContentView(mReactRootView);
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
@Override
protected void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostPause(this);
}
}
@Override
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostResume(this, this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostDestroy();
}
}
@Override
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
} else {
super.onBackPressed();
}
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
}
其中addPackage()添加的为RN和Android互调所需要的相关文件。具体可参照RN和Android互调的相关文件。
在RN自动生成的android项目中,采用集成ReactActivity的方式来加载RN的页面
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "Demo01";
}
}
需要自定义AppLication来完成相关参数配置
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();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
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());
}
/**
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
*
* @param context
* @param reactInstanceManager
*/
private static void initializeFlipper(
Context context, ReactInstanceManager reactInstanceManager) {
if (BuildConfig.DEBUG) {
try {
/*
We use reflection here to pick up the class that initializes Flipper,
since Flipper library is not available in release mode
*/
Class<?> aClass = Class.forName("com.demo01.ReactNativeFlipper");
aClass
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
.invoke(null, context, reactInstanceManager);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
List<ReactPackage> packages = new PackageList(this).getPackages();
点开PackageList的getPackages方法发现里面会自动配置一些所需要的packages
public ArrayList<ReactPackage> getPackages() {
return new ArrayList<>(Arrays.<ReactPackage>asList(
new MainReactPackage(mConfig),
new ImagePickerPackage()
));
}
如果没有使用PackageList的getPackages方法,可以参照其中的package手动配置到我们的项目中去