我将React Native集成到本机Android应用程序中,并从本机代码创建React Native活动的新实例。
以下是包装ReactInstanceManager的类的代码:
public class ReactNativeInstanceWrapper
{
private static ReactNativeInstanceWrapper instance = new ReactNativeInstanceWrapper();
public static ReactNativeInstanceWrapper getInstance() {
return instance;
}
private ReactInstanceManager reactInstanceManager;
public ReactInstanceManager GetReactInstanceManager()
{
return reactInstanceManager;
}
public ReactInstanceManager Rebuild(Application application)
{
Boolean isDebugBuild = AppBuildType.IsBuildConfigDebug(application.getBaseContext());
reactInstanceManager = null;
synchronized (this) {
reactInstanceManager = ReactInstanceManager.builder()
.setApplication(application)
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(new ReactIntegrationPackage())
.addPackage(new PickerPackage())
.addPackage(new LinearGradientPackage())
.setUseDeveloperSupport(isDebugBuild)
.setInitialLifecycleState(LifecycleState.BEFORE_CREATE)
.build();
}
if (!reactInstanceManager.hasStartedCreatingInitialContext())
{
reactInstanceManager.createReactContextInBackground();
}
return reactInstanceManager;
}
我希望在应用程序加载时解析js包并对其进行缓存,这样可以更快地加载React Native。问题是看起来在多个活动之间共享ReactInstanceManager会导致一些问题。
例如,在一种情况下,如果我在我的某个活动中打开一个共享表,而不是回到我的RN活动并关闭它,我就无法在新的RN活动中打开一个对话框。它抛出一个WindowManager $ BadTokenException,这可能意味着它试图将它附加到一个不存在的活动。
在RN活动中,以下是我在OnCreate中创建ReactRootView的方法:
this.ReactRootView = new ReactRootView(this);
setContentView(this.ReactRootView);
ReactNativeInstanceWrapper reactNativeInstanceWrapper = ReactNativeInstanceWrapper.getInstance();
this.ReactInstanceManager = reactNativeInstanceWrapper.GetReactInstanceManager();
if (this.ReactInstanceManager == null) {
this.ReactInstanceManager = ReactNativeInstanceWrapper.getInstance().Rebuild(getApplication());
}
this.ReactRootView.startReactApplication(this.ReactInstanceManager, reactNativeComponent, initialProps);
ReactInstanceManager应该在OnResume中设置一个新活动:
@Override
protected void onResume()
{
super.onResume();
if (this.ReactInstanceManager != null) {
this.ReactInstanceManager.onHostResume(this, this);
}
}
但看起来它仍然会在某处保留对旧活动的引用。
所以,我最终做的是每次离开RN活动时都会破坏并重建ReactInstanceManager的实例。它不是一个完美的选择,但它确实有效。
我想找到一种方法来创建和保存ReactInstanceManager的单个实例,而不是每次在后台重新创建它。
答案 0 :(得分:0)
这是我找到的解决方案。
我使用MutableContextWrapper创建了初始的ReactRootView。
ReactRootView reactRootView = new ReactRootView(new MutableContextWrapper(originActivity));
它允许我用OnCreate中的新上下文替换它
MutableContextWrapper contextWrapper = (MutableContextWrapper) reactRootView.getContext();
contextWrapper.setBaseContext(currentActivity);
这样,我可以预装整个东西,以后再使用。我偶然在github问题之一中找到了该解决方案。我希望有一个记录良好的方法。
在较早版本的React Native中,过去对模态对话框的引用也存在问题,但现在已解决。
答案 1 :(得分:0)
您有一个ReactNativeHost,其中包含您的ReactInstanceManager的一个实例
private ReactInstanceManager getReactInstanceManager() {
return reactNativeHost.getReactInstanceManager();
}