ReactNative创建原生模块

ReactNative创建原生模块

有时候我们需要使用某一模块,而ReactNative可能并没有对其进行包装,那么我们就可以自己实现该模块的封装,以Toast为例。

编写模块

package com.myproject;

import android.widget.Toast;

import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import java.util.HashMap;
import java.util.Map;

public class MyToastModule extends ReactContextBaseJavaModule{
    private static final String DURATION_SHORT_KEY = "SHORT";
    private static final String DURATION_LONG_KEY = "LONG";

    public MyToastModule(ReactApplicationContext reactContext){
        super(reactContext);
    }

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

    @Override
    public Map<String, Object> getConstants() {
        final Map<String, Object> constants = new HashMap<>();
        constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
        constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
        return constants;
    }

    @ReactMethod
    public void show(String message, int duration) {
        Toast.makeText(getReactApplicationContext(), message, duration).show();
    }
}

首先我们需要编写一个自定义模块的类,该类需要继承ReactContextBaseJavaModule,他可以实现javascript所需要的功能。我们这里的目标是可以在JavaScript里写ToastAndroid.show(‘Awesome’, ToastAndroid.SHORT);,来调起一个Toast通知。ReactContextBaseJavaModule要求派生类实现getName()方法,该方法会返回一个字符串名字,该名字会在JavaScript端标记这个模块,这里我们吧这个模块叫做ToastAndroid,这样我们就可以在JavaScript中通过React.NativeModules.ToastAndroid访问到这个模块。

然后我们可以看到有个getConstants方法,该方法会返回需要导出给JavaScript使用的常量,并不是必须要实现的方法,该例中,我们需要返回两个常量来设置Toast消息显示的时间长短,因此我们实现该方法,这样我们就可以在JavaScript中通过React.NativeModules.ToastAndroid.DURATION_SHORT_KEY 使用该常量。

最后是我们定义的show方法,该方法使用@ReactMethod进行注解,意思是导出给JavaScript进行使用,方法返回的类型必须为void。

这样我们就编写好了一个模块,接下来我们需要对该模块进行注册。

注册模块

package com.myproject;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * Created by ZhangYi on 2016/4/5.
 */
public class MyPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new MyToastModule(reactApplicationContext));
        return modules;
    }

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

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

如果我们已有自定义的Package继承自ReactPackage,那么只需要将注册的的模块添加到createNativeModules中的list中,如果没有,需要我们自定义一个Package,如上代码所示。

同时这个Package还需要添加到MainActivity中的getPackage方法中,如下代码所示:

package com.myproject;

import com.facebook.react.ReactActivity;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;

import java.util.Arrays;
import java.util.List;

public class MainActivity extends ReactActivity {

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "MyProject";
    }

    /**
     * Returns whether dev mode should be enabled.
     * This enables e.g. the dev menu.
     */
    @Override
    protected boolean getUseDeveloperSupport() {
        return BuildConfig.DEBUG;
    }

    /**
     * A list of packages used by the app. If the app uses additional views
     * or modules besides the default ones, add more packages here.
     */
    @Override
    protected List<ReactPackage> getPackages() {
        return Arrays.<ReactPackage>asList(
            new MainReactPackage(),
            new MyPackage()
        );
    }
}

这样我们就可以在JavaScript中进行调用了。

使用原生模块

因为我们对Anddroid代码进行了修改,因此需要我们重新进行编译运行。

最后只需要在JavaScript中获取原生模块,并进行调用即可:

    const MyToastAndroid = React.NativeModules.MyToastAndroid;
    MyToastAndroid.show("hello world,This is Toast Info!",MyToastAndroid.LONG);

注意需要导入NativeModules。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值