美文网首页
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