Android原生跳转React不同页面(undefined is not an object)
- 继续上篇文章的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页面)
代码如下:
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,注意这里有坑!!:
第四步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调用的是用会报错:
- 正确的姿势,将添加package的动作放在当前的activity中,Main2Activity:
好了这次就到这里吧~~
转载标明出处:http://www.cnblogs.com/no-coding
有问题邮件 nocoding@163.com QQ:418244382