Android原生项目Fragment中集成React Native
Android中集成ReactNative网上的方法众说纷纭,我试了好多也都可以实现,我挺迷茫的。最后我整理出了自己喜欢的一种方式。
有好多方法是在Application中实现ReactApplication,然后重写getReactNativeHost方法返回在Application中实例化的一个ReactNativeHost,在ReactNativeHost中有加载包、开发配置。这种方式比较适合单入口,即只有一个index.android.bundle存在。
以下是我喜欢的一种方式
Fragment基类
public abstract class ReactFragment extends Fragment {
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
private Bundle mBundle;
// This method returns the name of our top-level component to show
public abstract String getMainComponentName();
@Override
public void onAttach(Context context) {
super.onAttach(context);
mReactRootView = new ReactRootView(context);
}
public void setmReactInstanceManager(ReactInstanceManager mReactInstanceManager, Bundle bundle) {
this.mReactInstanceManager = mReactInstanceManager;
mBundle = bundle;
}
@Override
public ReactRootView onCreateView(LayoutInflater inflater, ViewGroup group, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
return mReactRootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mReactRootView.startReactApplication(
mReactInstanceManager,
getMainComponentName(),
mBundle
);
}
}
Fragment中继承ReactFragment
public class ReactUseInFragment extends ReactFragment{
@Nullable
@Override
public String getMainComponentName() {
//index.js中定义的组件名称
return "MyReactNativeApp";
}
}
Activity中
Activity必须要实现DefaultHardwareBackBtnHandler,否则手势或者按钮会出问题的
public class ReactUseInFragmentTwoActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
private ReactInstanceManager mReactInstanceManager;
private ReactRootView mReactRootView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_react_use_in_fragment_two);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(this.getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
ReactUseInFragmentTwo fragment = new ReactUseInFragmentTwo();
fragment.setmReactInstanceManager(mReactInstanceManager, null);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fl_react, fragment).show(fragment);
fragmentTransaction.commit();
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
@Override
public void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostPause(this);
}
}
@Override
public void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostResume(this, this);
}
}
@Override
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
} else {
super.onBackPressed();
}
}
总结
就是这么简单的方法,搞得我头很痛,ReactActivity里面的源码看得头也很痛。
mReactInstanceManager = ReactInstanceManager.builder() .setApplication(this.getApplication()) .setBundleAssetName("index.android.bundle") .setJSMainModulePath("index") .addPackage(new MainReactPackage()) .setUseDeveloperSupport(BuildConfig.DEBUG) .setInitialLifecycleState(LifecycleState.RESUMED) .build(); mReactInstanceManager = new ReactNativeHost(getActivity().getApplication()) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage() ); } @Override protected String getJSMainModuleName() { return "index"; } @Nullable @Override protected String getBundleAssetName() { return "index.android.bundle"; } }.getReactInstanceManager();
这两种写法类似,获得的mReactInstanceManager是一样的