美文网首页
Android ReactNative数据交互

Android ReactNative数据交互

作者: 蒲小帅丶 | 来源:发表于2018-04-21 11:38 被阅读0次

    1.android跳转界面,和React native初始化参数的传递

    实现效果:点击按钮,跳转到加载 react native的activityA,让A传递不同的值过去,让RN.js显示不同的界面。

    1.androind加载reactnative有两种方式,一种是继承ReactAcitivity通过重写getMainComponentName()指定reactnative入口文件的方式加载。

    public class ThreeActivity extends ReactActivity {
     
        @Override
        protected String getMainComponentName() {
            return "androidrn";//这是在package.json的文件的name要相同
        }
        @Override
        protected ReactActivityDelegate createReactActivityDelegate() {
            return new MyreactDelegate(this, getMainComponentName());
        }
        class MyreactDelegate extends ReactActivityDelegate {
    
            public MyreactDelegate(Activity activity,    @Nullable String mainComponentName) {
                super(activity, mainComponentName);
            }
            @Nullable
            @Override
            protected Bundle getLaunchOptions() {
                Bundle bundle = new Bundle();
                bundle.putString("fromtag", "C");
                bundle.putString("data3", "android传递的初始化参数");
                return bundle;
            }
        }
    }
    
    image.png

    这是一种方式传递。
    2.第二种方式就是将reactnative作为view来使用,添加到布局文件。

    public abstract class BaseReactActivity extends AppCompatActivity  implements DefaultHardwareBackBtnHandler {
        private ReactRootView mReactRootView;
        private ReactInstanceManager mReactInstanceManager;
        public static int OVERLAY_PERMISSION_REQ_CODE = 300;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!Settings.canDrawOverlays(this)) {
                    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                            Uri.parse("package:" + getPackageName()));
                    startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
                }
            }
            initData();
            mReactRootView = new ReactRootView(this);
            mReactInstanceManager = ReactInstanceManager.builder()
                    .setApplication(getApplication())
                    .setBundleAssetName("index.android.bundle")
                    .setJSMainModulePath("index.android")
                    .addPackage(new MainReactPackage())
                    .setUseDeveloperSupport(true)
                    .setInitialLifecycleState(LifecycleState.RESUMED)
                    .build();
            // “AppRegistry.registerComponent()”的第一个参数
            mReactRootView.startReactApplication(mReactInstanceManager, "dachuan",getBundle());
            setContentView(mReactRootView);
    
    
        }
    
        public abstract Bundle  getBundle() ;
    
        public abstract void initData();
        @Override
        public void invokeDefaultOnBackPressed() {
            ToastUtils.showShortToast("js默认返回结束调用执行Activity销毁");
            super.onBackPressed();
        }
        @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 onBackPressed() {
    
            if (mReactInstanceManager != null) {
                mReactInstanceManager.onBackPressed();
                ToastUtils.showShortToast("js返回");
            } else {
                super.onBackPressed();
                ToastUtils.showShortToast("走这里");
            }
    
        }
        @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 onActivityResult(int requestCode, int resultCode, Intent data) {
            if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (!Settings.canDrawOverlays(this)) {
                        // SYSTEM_ALERT_WINDOW permission not granted...
                    }
                }
            }
        }
    }
    

    这样写个抽象类把相同的操作封装下。

    public class NewsActivity extends BaseReactAcitvity {
       Bundle mBundle;
        @Override
        public Bundle getBundle() {
            mBundle=new Bundle();
            mBundle.putString("fromtag","B");
            mBundle.putString("data2","我是新闻界面");
            return mBundle;
        }
        @Override
        public void doLogicBeforeInitView() {
    
        }
    }
    

    继承下,就能有值了。
    3.接受数据并显示。因为可能跳转不同页面,所以传个fromtag区分下。
    在index.android.js中接收

    import React, { Component } from 'react';
    import {Text, AppRegistry, Image, View,StyleSheet} from 'react-native';
    export default class HelloWorldApp extends Component {
        render() {
          var data1=  this.props.data1;
          var data2=  this.props.data2;
          var data3=  this.props.data3;
          var tagfrom=this.props.fromtag;
          if (tagfrom=='A')
          {
              return (
                  <Text>{data1}</Text>
              );
          }else if (tagfrom=='B'){
              return (
                  <Text>{data2}</Text>
              );
          }
          else if (tagfrom=='C'){
                    return (
                        <View>
                        <Text>{data3}</Text>
                        <Image style={styles.img} source={require('./imgs/myicon.jpg')} />
                        </View>
                    );
                }
        }
    }
    var styles = StyleSheet.create({
        img:
            {
              width:300,
              height:300
            },
        container: {
            flex: 1,
            justifyContent: 'center',
        },
        hello: {
            fontSize: 20,
            textAlign: 'center',
            margin: 10,
        },
    });
    AppRegistry.registerComponent('androidrn', () => HelloWorldApp);
    

    用this.props.data1接收。data1要对应哟

    相关界面

    跳转的界面 image.png

    2.React Native 跳转android原生界面,并传值

    大致的实现步骤如下:
    1.RCTDeviceEventEmitter
    优点:可任意时刻传递,Native主导控制。
    2.Callback
    优点:JS调用,Native返回。 缺点:CallBack为异步操作,返回时机不确定
    3.Promise
    优点:JS调用,Native返回。 缺点:每次使用需要JS调用一次
    (1)定义Module类,继承ReactContextBaseJavaModule在Module类中,我们定义交互的方法,例如RN调用Native的方法,Native调用RN的方法等。
    (2)定义Package类,继承ReactPackage实现Package的createNativeModules方法,将Module实例添加到集合。
    (3)定义Application,继承ReactApplication实现getPackages方法,将Package实例添加到getPackages下的集合。
    该文没有描述这3种方式
    a.在android中定义MyMapIntentModule ,@ReactMethod创建跳转方法,并传值

    public class MyMapIntentModule extends ReactContextBaseJavaModule  {
        public static final String REACTCLASSNAME = "MyMapIntentModule";
        private Context mContext;
        public MyMapIntentModule(ReactApplicationContext reactContext) {
            super(reactContext);
            mContext=reactContext;
        }
        @Override
        public String getName() {
            return REACTCLASSNAME;
        }
        @ReactMethod
        public  void startAcByClassName(String name, String  bundle)
        {
            try {
           Activity currentActivity =getCurrentActivity();
           if (null!=currentActivity)
           {
               Class toActivity=Class.forName(name);
               Intent intent=new Intent(currentActivity,toActivity);
               intent.putExtra("nativedata",bundle);
               currentActivity.startActivity(intent);
           }
    
            }catch (Exception e)
            {
                throw new JSApplicationIllegalArgumentException(
                        "无法打开activity页面: "+e.getMessage());
            }
        }
    }
    

    b.定义MyreactPackage ,添加到列表中。

    public class MyreactPackage implements ReactPackage {
        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
            List<NativeModule> modules=new ArrayList<>();
            modules.add(new MyMapIntentModule(reactContext));
            return modules;
        }
    
        @Override
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
            return Collections.emptyList();
        }
    }
    

    c.在baseapplication中注册,仅仅在这里注册是会报错的。


    image.png

    报错如下:


    image.png
    需要怎么做呢?
    image.png

    这样就可以了。

    d .index.android.js中怎么写的呢?

    1)导入NativeModules

    import {Text, AppRegistry, Image, View,StyleSheet,Button,NativeModules} from 'react-native';
    
    <Button style={styles.container} title="点击跳转" onPress={() => this.onClick()}></Button>
    
     onClick() {
            NativeModules.MyMapIntentModule.startAcByClassName("ph.com.test.AndroidNativeActivity","我是index,android.js中的信息")
        }
    
    image.png
    对应 image.png
    到此就完成跳转传值了。
    感谢文章的作者:链接

    相关文章

      网友评论

          本文标题:Android ReactNative数据交互

          本文链接:https://www.haomeiwen.com/subject/tsszkftx.html