React Native创建原生模块
在React Native开发中,有时我们需要使用某些功能,但React Native本身并未提供相应的模块封装。这时,我们可以自己实现原生模块的封装。本文以Android平台上的Toast通知为例,详细介绍如何创建和使用React Native原生模块。
编写模块
首先,我们需要编写一个自定义模块类,该类继承自ReactContextBaseJavaModule,用于实现JavaScript所需的功能。例如,我们的目标是能够在JavaScript中调用ToastAndroid.show('Awesome', ToastAndroid.SHORT);来显示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要求派生类实现getName()方法,该方法返回一个字符串名称,用于在JavaScript端标识这个模块。这里我们将模块命名为ToastAndroid,以便在JavaScript中通过React.NativeModules.ToastAndroid访问。
getConstants方法用于导出给JavaScript使用的常量,这不是必须实现的方法。在本例中,我们返回两个常量来设置Toast消息的显示时长,从而在JavaScript中通过React.NativeModules.ToastAndroid.DURATION_SHORT_KEY使用这些常量。
show方法使用@ReactMethod注解,表示导出给JavaScript使用,方法返回类型必须为void。
注册模块
编写好模块后,需要对其进行注册。如果已有自定义的Package继承自ReactPackage,只需将模块添加到createNativeModules方法的列表中。如果没有,需要自定义一个Package。
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.Collections;
import java.util.List;
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添加到MainActivity的getPackages方法中。
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 {
@Override
protected String getMainComponentName() {
return "MyProject";
}
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new MyPackage()
);
}
}
这样,模块就注册完成,可以在JavaScript中调用了。
使用原生模块
由于修改了Android代码,需要重新编译运行应用。在JavaScript中,获取原生模块并进行调用。
const MyToastAndroid = React.NativeModules.ToastAndroid;
MyToastAndroid.show("hello world, This is Toast Info!", MyToastAndroid.LONG);
注意,使用前需要导入NativeModules。通过以上步骤,即可成功创建并使用React Native原生模块,扩展应用功能。