美文网首页
RN调用原生视图填坑记录

RN调用原生视图填坑记录

作者: 捉影T_T900 | 来源:发表于2021-09-25 19:17 被阅读0次

    已有的APP是个什么状态?

    当前已有的APP本质是一个纯原生的应用,用java代码实现的基础容器。

    ReactNative充当一个什么角色?

    由于历史原因,已有业务中ReactNative已经作为RN插件的形式在上层进行各种设备独立操作界面的渲染,实现针对各个设备的控制逻辑。

    如果ReactNative插件想使用底层能力怎么办?例如相机、音视频编解码、数据库等重业务功能

    使用RreactNative官方支持的和原生逻辑交互解决方案。通过

    com.facebook.react.bridge
    

    包下数据封装方法实现RN和原生层面的数据流转

    准备工作

    1、在Activity指定Package

    mReactInstanceManager = ReactInstanceManager.builder()
                    .setApplication(getApplication())
                    .setJSBundleFile(path)
                    .setJSMainModulePath("ReactNative")
                    .addPackage(new DevicePackage())
                    .setUseDeveloperSupport(deugable)
                    .setInitialLifecycleState(LifecycleState.RESUMED)
                    .build();
    

    2、Package中指定NativeModule、ViewManager

        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
            List<NativeModule> modules = new ArrayList<>();
            modules.add(new LivePlayNativeModule(reactContext));
            modules.add(new CloudPlayNativeModule(reactContext));
            modules.add(new SDCardPlayNativeModule(reactContext));
            return modules;
        }
    
        @Override
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
            return Arrays.<ViewManager>asList(
                    new LivePlayViewManager(),
                    new CloudPlayViewManager(),
                    new SDCardPlayViewManager()
            );
        }
    

    3、NativeModule、ViewManager的对应关系和作用

    NativeModule对应js文件内的js方法

    通过 @ReactMethod 注解指定js、原生方法,返回数据使用  Promise 对象
    

    ViewManager对应js文件中控件的属性、状态的回调

    通过 @ReactProp(name = "videoPlayParam") 注解指定RN控件属性,属性值变化后会触发这个原生方法的调用
    

    遇到的深坑

    1、属性值是一个集合怎么在原生代码接收?

    通过 ReadableMap 对象接收参数集合
        @ReactProp(name = "videoPlayParam")
        public void setVideoPlayParam(QHVCTextureView view, ReadableMap params) 
    

    2、关于js中被动接收原生上行数据

    在ViewManager中,重写【addEventEmitters】方法,以及重写【getExportedCustomBubblingEventTypeConstants】方法

    定义原生、js事件对应方法名称key

        public static final String EVENT_NATIVE_PLAYERSTATUSCHANGE_NAME = "onNativePlayerStatusChange";
        public static final String EVENT_JS_PLAYERSTATUSCHANGE_NAME = "onPlayerStatusChange";
    

    getExportedCustomBubblingEventTypeConstants 中注册绑定原生、js对应方法。注意,!!!!phasedRegistrationNames, bubbled 这两个key为固定值!!!!!

        @Override
        public Map<String, Object> getExportedCustomBubblingEventTypeConstants() {
    
            LogUtils.i(TAG, "getExportedCustomBubblingEventTypeConstants");
    
            return MapBuilder.<String, Object>builder()
                    .put(EVENT_NATIVE_PLAYERSTATUSCHANGE_NAME,
                            MapBuilder.of("phasedRegistrationNames", MapBuilder.of("bubbled", EVENT_JS_PLAYERSTATUSCHANGE_NAME)))
                    .build();
        }
    

    向js写入回调数据

                    // 返回数据到RN
                    WritableMap dataMap = Arguments.createMap();
                    dataMap.putInt("playerStatus", playerStatus);
                    reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
                            view.getId(),
                            EVENT_NATIVE_PLAYERSTATUSCHANGE_NAME,
                            dataMap
                    );
    

    js中接收返回的原生数据

    //通过PropTypes来说明这个组件的接口
    CloudPlayView.propTypes = {
        /**
         * 播放器状态回调
         * 内容格式: {"playerStatus":1,"ratio":0.75}
         * playStatus枚举如下:(ratio仅在playerStatus为1的情况下才有值)
         * 0-视频流已准备好,默认自动播放
         * 1-视频长宽比变化 
         * 2-视频第一帧绘制完成,应该隐藏loading蒙层
         * 3-开始缓冲,应该显示loading蒙层
         * 4-缓冲结束,应该隐藏loading蒙层
         * 5-播放完成
         */
        onPlayerStatusChange: PropTypes.func,
    }
    
    <RNCloudPlayView onPlayerStatusChange={this._onPlayerStatusChange} />
    
        _onPlayerStatusChange = (event) => {
            if (!this.props.onPlayerStatusChange) {
                return;
            }
            //process raw event...
            this.props.onPlayerStatusChange(event.nativeEvent);
        }
    

    done

    相关文章

      网友评论

          本文标题:RN调用原生视图填坑记录

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