前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android与RN层的交互

Android与RN层的交互

作者头像
xiangzhihong
发布2022-11-30 15:12:26
5300
发布2022-11-30 15:12:26
举报
文章被收录于专栏:向治洪

Android跳转到RN页面 由于主客是以插件化的方式集成功能插件的,所以在主客中Android跳转到RN页面需要plugin、module和component。plugin、module不过多解释,component对应的是具体的js页面,要成功启动此页面,需要在对应的RN二方库中注册此页面。例如:

AppRegistry.registerComponent(‘MyDoctors’, () => MyDoctors); 注:至于为什么写一个RN的Component,然后系统就能启动,可以自己新建一个RN的工程,然后看下React Native启动流程分析。

Android与RN页面的交互 普通流程 RN如何调用原生Android的原生功能 rn调用原生的Android功能分为以下几步:

1,自定义原生实现类;

2,注册实现类;

3,RN的js部分调用原生;

首先,创建一个继承ReactContextBaseJaveModule的抽象类,此抽象类需要重写getName()函数用于返回一个字符串,这个字符串会在JavaScript端标记使用的模块。然后,可以编写一个函数暴露给javascript端,并且这个函数需要使用注解@ReactMethod进行标记。由于React Native的跨语言访问是异步进行的,所以想要给JavaScript返回一个值的唯一办法是使用回调函数或者发送事件。

例如,SomeModule:

代码语言:javascript
复制
package com.untitled;

import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import javax.annotation.Nonnull;

public class SomeModule extends ReactContextBaseJavaModule {

    public SomeModule(@Nonnull ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Nonnull
    @Override
    public String getName() {
        return "SomeModule";
    }

    @ReactMethod
    public void callbackMethod(String paramsFromJS, Callback ok, Callback error) {
        boolean result = true;
        if (result) {
            ok.invoke("callback ok");
        } else {
            error.invoke("callback ok");
        }
    }

    @ReactMethod
    public void promiseMethod(String paramsFromJS, Promise promise){
        boolean result = true;
        if (result) {
            promise.resolve("promise ok");
        } else {
            promise.reject("promise error");
        }
    }
}

然后,需要创建一个实现类用于实现ReactPackage接口,该接口中有三个抽象函数需要实现,分别是createNativeModules,createJSModules,createViewManagers。其中,ReactPackage实现类最关键的函数就是createNativeModules,在该函数中我们需要添加前一步创建的ReactContextBaseJavaModule子类用于构建ReactInstanceManager的实例,并通过调用 addPackage()函数,将上一步实现的ReactPackage添加进去。

例如,SomeReactPackage:

代码语言:javascript
复制
public class SomeReactPackage implements ReactPackage {

    @Nonnull
    @Override
    public List<NativeModule> createNativeModules(@Nonnull ReactApplicationContext reactContext) {
        List modules=new ArrayList<>();
        SomeModule module = new SomeModule(reactContext);
        modules.add(module);
        return modules;
    }

    @Nonnull
    @Override
    public List<ViewManager> createViewManagers(@Nonnull ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }
}

接下来,还需要在MainPackage类的getPackages()方法中添加注册这个自定义的模块。

代码语言:javascript
复制
public class MainApplication extends Application implements ReactApplication {

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                    new MainReactPackage(),
                    new SomeReactPackage()   //注册自定义模块
            );
        }

        @Override
        protected String getJSMainModuleName() {
            return "index";
        }
    };

    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        SoLoader.init(this, /* native exopackage */ false);
    }
}

一般来说,到此原生模块部分就可以了。接下来,在RN的js端就可以调用原生模块的函数了,流程还是比较清楚的。

代码语言:javascript
复制
export default class MainPage extends Component<Props> {

    constructor(props) {
        super(props);
        this.callBack = this.callBack.bind(this);
        this.promissCallback = this.promissCallback.bind(this);
    }

    callBack() {
        NativeModules.SomeModule.callbackMethod('params', (result) => {
            console.log('callBack ok======>' + result)
        }, (error) => {
            console.log('callBack error======>' + error)
        });
    }

    promissCallback() {
        NativeModules.SomeModule.promiseMethod('params').then((result) => {
            console.log('Promiss ok======>' + result)
        }).catch((error) => {
            console.log('Promiss error======>' + result)
        });
    }

    render() {
        return (
            <View style={styles.container}>
                <TouchableOpacity onPress={this.callBack} style={styles.bindButtonStyle}>
                    <Text style={styles.submitStyle}>回调方式</Text>
                </TouchableOpacity>
                <TouchableOpacity onPress={this.promissCallback} style={styles.bindButtonStyle}>
                    <Text style={styles.submitStyle}>Promiss方式</Text>
                </TouchableOpacity>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
    },
    bindButtonStyle: {
        backgroundColor: '#42B3E3',
        borderRadius: 22,
        height: 44,
        marginRight: 15,
        marginLeft: 15,
        marginTop: 20,
        justifyContent: 'center'
    },
    submitStyle: {
        alignSelf: 'center',
        fontSize: 16,
        color: 'white'
    },
});

最后,启动上面的项目,既可以看到js调用原生部分输出的数据,如下图。

注意:boolean、int、double、float、String这些java的基本值类型都可以转,但是不能直接使用object类型进行相互调用。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档