上一篇文章写了如何配置RN和Android原生混合开发的相关配置

Android 模块引入ReactNative相关环境配置

下面整理一下如何在原声项目中加载一个RN的页面,主要是加载一个bundle文件

1.使用RN生成bundle文件

首先在RN的android项目下新建assets文件夹,project结构下右击main文件夹,新建一个名字为assets的文件夹

ea9634bca4d5

image.png

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 getPackages() {

@SuppressWarnings("UnnecessaryLocalVariable")

List 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 packages = new PackageList(this).getPackages();

点开PackageList的getPackages方法发现里面会自动配置一些所需要的packages

public ArrayList getPackages() {

return new ArrayList<>(Arrays.asList(

new MainReactPackage(mConfig),

new ImagePickerPackage()

));

}

如果没有使用PackageList的getPackages方法,可以参照其中的package手动配置到我们的项目中去

ea9634bca4d5

image.png

Logo

智屏生态联盟致力于大屏生态发展,利用大屏快应用技术降低开发者开发、发布大屏应用门槛

更多推荐