Android原生跳转React不同页面(undefined is not an object)

时间:2021-08-24 06:19:46
  • 继续上篇文章的demo,由于现在的项目是原生的,打算用部分页面试下react native,那么问题来了:react貌似只有一个入口 index.android.js,那么在不同的原生页面需要跳转到不同的页面怎么解决呢?

  这里小主网上转了下,想了一个办法,原生向react传递数据,根据不同数据在index.android.js中跳转不同的页面,竟然要传递数据,那么就涉及到原生于JS的交互了:

  •   小主这里使用的是经典的CallBack方式:

  第一步创建module:

  

public class JsAndroidModule extends ReactContextBaseJavaModule {
private static final String MODULE_NAME = "JsAndroid";
private Context mContext = null; public JsAndroidModule(ReactApplicationContext reactContext) {
super(reactContext);
mContext = reactContext;
} @Override
public String getName() {
return MODULE_NAME;
} @ReactMethod
public void jsActivity(Callback successBack, Callback erroBack) {
try {
Activity currentActivity = getCurrentActivity();
int result = currentActivity.getIntent().getIntExtra("data", 0);//会有对应数据放入
successBack.invoke(result);
} catch (Exception e) {
erroBack.invoke(e.getMessage());
}
}
}

这里注意: 小主是从一个原生的activity跳转到activity2(react页面)

Android原生跳转React不同页面(undefined is not an object)

代码如下:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.text1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, Main2Activity.class);
intent.putExtra("data", 1);
startActivity(intent);
}
});
findViewById(R.id.text2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, Main2Activity.class);
intent.putExtra("data", 2);
startActivity(intent);
}
});
}

JsAndroidModule  getcurrentActiviey().getIntent().getIntExtra("data", 0) 获取的data正是这里传入的。

  • Main2Activity的代码:

  

public class Main2Activity extends Activity implements DefaultHardwareBackBtnHandler {
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main2);
try {
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(new JsReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "reactnative", null);
setContentView(mReactRootView);
} catch (Exception e) {
Log.e(this.getClass().getName(), e.getCause().getMessage());
}
} @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(this);
}
} @Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
}

这里同样要注意一点 : Activity一定要继承 DefaultHardwareBackBtnHandler,不然JsAndroidModule  中 getcurrentactivity() 为null.

第二步创建package:

public class JsReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new JsAndroidModule(reactContext));
return modules;
} @Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
} @Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

第三步添加package,注意这里有坑!!:

Android原生跳转React不同页面(undefined is not an object)

第四步JS调用:

 constructor(props) {
super(props);
this.state = {
pageIndex: 0
}
this.getNativeData();
} getNativeData() {
NativeModules.JsAndroid.jsActivity(
(successMsg) => {
this.setState({
pageIndex: successMsg
}
);
},
(erroMsg) => {
alert(erroMsg)
}
);
}
render() {
var defaultName = 'MainPage';
var defaultComponent = MainPage;
console.log(this.state.pageIndex);
if (this.state.pageIndex == 1) {  //根据传递过来的数据跳转不同的页面
return (<MainPage/>);
} else {
return (<SecondPage/>);
}
}
 

网上各种demo将添加package的方式都放在application的host里面,可能是受 官方demo 的影响,毕竟官方也是这么写的...如果把添加package的动作放到applicationhost那么js调用的是用会报错:

Android原生跳转React不同页面(undefined is not an object)

  • 正确的姿势,将添加package的动作放在当前的activity中,Main2Activity:

  Android原生跳转React不同页面(undefined is not an object)

好了这次就到这里吧~~