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:

  

 好了这次就到这里吧~~

 

   

posted @ 2017-02-15 15:31  no-coding  阅读(2686)  评论(0编辑  收藏  举报