react-native之native主动向js发送事件

来源:互联网 发布:优化速度插件下载 编辑:程序博客网 时间:2024/06/01 10:39

1:新建react-native项目 将andorid部分导入到Androidstudio中

2:写一个事件发送的方法

代码如下:

    private void sendEvent(ReactContext reactContext,                           String eventName,                           @Nullable WritableMap params) {        if (reactContext==null) {            Log.i(TAG, "reactContext==null");        }else{            reactContext                    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)                    .emit(eventName, params);        }    }
注意:   这里要使用到reactContext作为参数,但是在新版本react-native中新建的项目是继承自reactactivity

                   这样的public class MainActivity extends ReactActivity 

                   ReactActivity 中有有这么一个变量 private @Nullable ReactInstanceManager mReactInstanceManager;但这是private的 外部无法访问 

                   因此我们需要自己替代reactactivity,实现DefaultHardwareBackBtnHandler相关方法

                   否者会出现null异常

代码如下:

package com.wyq;import android.app.Activity;import android.content.Intent;import android.os.Build;import android.os.Bundle;import android.os.Handler;import android.os.PersistableBundle;import android.provider.Settings;import android.support.annotation.Nullable;import android.util.Log;import android.view.KeyEvent;import android.widget.EditText;import android.widget.Toast;import com.facebook.common.logging.FLog;import com.facebook.react.LifecycleState;import com.facebook.react.ReactActivity;import com.facebook.react.ReactInstanceManager;import com.facebook.react.ReactPackage;import com.facebook.react.ReactRootView;import com.facebook.react.bridge.Arguments;import com.facebook.react.bridge.ReactContext;import com.facebook.react.bridge.WritableMap;import com.facebook.react.common.ReactConstants;import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;import com.facebook.react.modules.core.DeviceEventManagerModule;import com.facebook.react.shell.MainReactPackage;import java.util.Arrays;import java.util.List;public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler{    private static final String TAG="react-native";    private static final String REDBOX_PERMISSION_MESSAGE =            "Overlay permissions needs to be granted in order for react native apps to run in dev mode";    private @javax.annotation.Nullable ReactInstanceManager mReactInstanceManager;    private LifecycleState mLifecycleState = LifecycleState.BEFORE_RESUME;    private boolean mDoRefresh = false;    protected @javax.annotation.Nullable String getBundleAssetName() {        return "index.android.bundle";    }    protected @javax.annotation.Nullable String getJSBundleFile() {        return null;    }    protected String getJSMainModuleName() {        return "index.android";    }    protected String getMainComponentName() {        return "wyq";    }    protected boolean getUseDeveloperSupport() {        return BuildConfig.DEBUG;    }    protected List<ReactPackage> getPackages() {        return Arrays.<ReactPackage>asList(                new MainReactPackage(),new AnExampleReactPackage());    }    protected ReactInstanceManager createReactInstanceManager() {        ReactInstanceManager.Builder builder = ReactInstanceManager.builder()                .setApplication(getApplication())                .setJSMainModuleName(getJSMainModuleName())                .setUseDeveloperSupport(getUseDeveloperSupport())                .setInitialLifecycleState(mLifecycleState);        for (ReactPackage reactPackage : getPackages()) {            builder.addPackage(reactPackage);        }        String jsBundleFile = getJSBundleFile();        if (jsBundleFile != null) {            builder.setJSBundleFile(jsBundleFile);        } else {            builder.setBundleAssetName(getBundleAssetName());        }        return builder.build();    }    protected ReactRootView createRootView() {        return new ReactRootView(this);    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        if (getUseDeveloperSupport() && Build.VERSION.SDK_INT >= 23) {            // Get permission to show redbox in dev builds.            if (!Settings.canDrawOverlays(this)) {                Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);                startActivity(serviceIntent);                FLog.w(ReactConstants.TAG, REDBOX_PERMISSION_MESSAGE);                Toast.makeText(this, REDBOX_PERMISSION_MESSAGE, Toast.LENGTH_LONG).show();            }        }        mReactInstanceManager = createReactInstanceManager();        ReactRootView mReactRootView = createRootView();        mReactRootView.startReactApplication(mReactInstanceManager, getMainComponentName());        setContentView(mReactRootView);        Log.i(TAG, "onCreate");    }    @Override    protected void onPostResume() {        super.onPostResume();    }    <strong><span style="font-size:18px;">/*事件发送函数*/</span></strong>    private void sendEvent(ReactContext reactContext,                           String eventName,                           @Nullable WritableMap params) {        if (reactContext==null) {            Log.i(TAG, "reactContext==null");        }else{            reactContext                    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)                    .emit(eventName, params);        }    }    @Override    protected void onPause() {        super.onPause();        mLifecycleState = LifecycleState.BEFORE_RESUME;        if (mReactInstanceManager != null) {            mReactInstanceManager.onPause();        }    }    @Override    protected void onResume() {        super.onResume();        mLifecycleState = LifecycleState.RESUMED;        if (mReactInstanceManager != null) {            mReactInstanceManager.onResume(this, this);           <strong><span style="font-size:18px;"> WritableMap params = Arguments.createMap();            params.putBoolean("wyq",true);            sendEvent(mReactInstanceManager.getCurrentReactContext(), "wyq", params);</span></strong>        }    }    @Override    protected void onDestroy() {        super.onDestroy();        if (mReactInstanceManager != null) {            mReactInstanceManager.onDestroy();        }    }    @Override    public void onActivityResult(int requestCode, int resultCode, Intent data) {        if (mReactInstanceManager != null) {            mReactInstanceManager.onActivityResult(requestCode, resultCode, data);        }    }    @Override    public boolean onKeyUp(int keyCode, KeyEvent event) {        if (mReactInstanceManager != null &&                mReactInstanceManager.getDevSupportManager().getDevSupportEnabled()) {            if (keyCode == KeyEvent.KEYCODE_MENU) {                mReactInstanceManager.showDevOptionsDialog();                return true;            }            if (keyCode == KeyEvent.KEYCODE_R && !(getCurrentFocus() instanceof EditText)) {                // Enable double-tap-R-to-reload                if (mDoRefresh) {                    mReactInstanceManager.getDevSupportManager().handleReloadJS();                    mDoRefresh = false;                } else {                    mDoRefresh = true;                    new Handler().postDelayed(                            new Runnable() {                                @Override                                public void run() {                                    mDoRefresh = false;                                }                            },                            200);                }            }        }        return super.onKeyUp(keyCode, event);    }    @Override    public void onBackPressed() {        if (mReactInstanceManager != null) {            mReactInstanceManager.onBackPressed();        } else {            super.onBackPressed();        }    }    @Override    public void invokeDefaultOnBackPressed() {        super.onBackPressed();    }}


好吧我知道这样太麻烦了

 来个简单直接的

在mainactivity里面

    public void sendEvent(String eventName, @Nullable WritableMap params) {        if(mainreactContext==null){            //可以得到mainreactContext值            mainreactContext = this.getReactNativeHost().getReactInstanceManager().getCurrentReactContext();        }        if(ad){            ad = false;            if (mainreactContext==null) {                Log.i(TAG, "mainreactContext==null");            }else{                Log.i(TAG,"sendADEvent:"+params.toString());                mainreactContext                        .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)                        .emit(eventName, params);            }        }    }

亲测有效


本地代码部分完成,下面看js代码

1:在index.android.js中注册监听

     代码如下:

'use strict';import React, {  AppRegistry,  Component,  StyleSheet,  Text,  View,  NativeModules,  DeviceEventEmitter<strong><span style="font-size:18px;">//注意:要使用这个 使用RCTDeviceEventEmitter不识别(和文档说好的不一样 不知道为什么)</span></strong>} from 'react-native';class wyq extends Component {   //mixins:[Subscribable.Mixin];  componentWillMount(){ <strong><span style="font-size:18px;">//注册监听</span></strong>                    DeviceEventEmitter.addListener('wyq', function(e: Event) {                         alert("event listener success");                       }); }  render() {    return (      <View style={styles.container}>        <Text style={styles.welcome}>          Welcome to React Native!        </Text>        <Text style={styles.instructions}>          To get started, edit index.android.js        </Text>        <Text style={styles.instructions}>          Shake or press menu button for dev menu        </Text>      </View>    );  }}const styles = StyleSheet.create({  container: {    flex: 1,    justifyContent: 'center',    alignItems: 'center',    backgroundColor: '#F5FCFF',  },  welcome: {    fontSize: 20,    textAlign: 'center',    margin: 10,  },  instructions: {    textAlign: 'center',    color: '#333333',    marginBottom: 5,  },});AppRegistry.registerComponent('wyq', () => wye);



运行如图:


事件发送成功



          

0 0
原创粉丝点击