Android原生跳轉React不一樣頁面(undefined is not an object)

  • 繼續上篇文章的demo,因爲如今的項目是原生的,打算用部分頁面試下react native,那麼問題來了:react貌似只有一個入口 index.android.js,那麼在不一樣的原生頁面須要跳轉到不一樣的頁面怎麼解決呢?

  這裏小主網上轉了下,想了一個辦法,原生向react傳遞數據,根據不一樣數據在index.android.js中跳轉不一樣的頁面,居然要傳遞數據,那麼就涉及到原生於JS的交互了:html

 

  •   小主這裏使用的是經典的CallBack方式:

  第一步建立module:react

  

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

代碼以下:面試

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正是這裏傳入的。app

  • 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.ide

第二步建立package:ui

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,注意這裏有坑!!:this

 

第四步JS調用:spa

 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調用的是用會報錯:.net

 

  •  正確的姿式,將添加package的動做放在當前的activity中,Main2Activity:

  

 好了此次就到這裏吧~~

相關文章
相關標籤/搜索