前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React Native使用原生组件

React Native使用原生组件

作者头像
xiangzhihong
发布2018-02-05 21:09:12
2.1K0
发布2018-02-05 21:09:12
举报
文章被收录于专栏:向治洪向治洪

概述

有时候App需要访问平台API,但React Native可能还没有相应的模块包装;或者你需要复用一些Java代码,而不是用Javascript重新实现一遍;又或者你需要实现某些高性能的、多线程的代码,譬如图片处理、数据库、或者各种高级扩展等等。 我们知道React Native本身对这种偏业务和底层调用是不关心的,这时候我们就想到了原生组件,我们通过调用原生组件,然后经过特定的封装来达到效果。如我们在原生开发中常见的Toast为例:

原生模块封装

假设我们希望可以从Javascript发起一个Toast消息,Android会显示在屏幕的下方,会停留一段时间。我们来看一下官方给出的例子。

创建一个继承了ReactContextBaseJavaModule的Java类,它可以实现一些JavaScript所需的功能。我们这里的目标是可以在JavaScript里写ToastAndroid.show(‘Awesome’, ToastAndroid.SHORT);,来调起一个Toast通知。

代码语言:javascript
复制
package com.facebook.react.modules.toast;

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.Map;

public class ToastModule extends ReactContextBaseJavaModule {

  private static final String DURATION_SHORT_KEY = "SHORT";
  private static final String DURATION_LONG_KEY = "LONG";

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

ReactContextBaseJavaModule要求派生类实现getName方法,这个名字返回的字符串可以自取,但是不能命名为’ToastAndroid’,因为RN已经内置了一个名为ToastAndroid的模块,运行时会报错名字冲突!

代码语言:javascript
复制
  @Override
  public String getName() {
    return "ToastAndroid";
  }

注:模块名前的RCT前缀会被自动移除。所以如果返回的字符串为”RCTToastAndroid”,在JavaScript端依然通过React.NativeModules.ToastAndroid访问到这个模块。 接下来我们需要设置一个可选的方法getContants(),用于弹出时间选择(及Toast.Length)

代码语言:javascript
复制
 @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;
  }

最后导出一个方法给JavaScript使用。

代码语言:javascript
复制
 @ReactMethod
  public void show(String message, int duration) {
    Toast.makeText(getReactApplicationContext(), message, duration).show();
  }

在Java这边要做的最后一件事就是注册这个模块。我们需要在应用的Package类的createNativeModules方法中添加这个模块。如果模块没有被注册,它也无法在JavaScript中被访问到。

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

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

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

  @Override
  public List<NativeModule> createNativeModules(
                              ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();

    modules.add(new ToastModule(reactContext));

    return modules;
  }

这个package需要在MainApplication.java文件的getPackages方法中提供。这个文件位于你的react-native应用文件夹的android目录中。具体路径是: android/app/src/main/java/com/your-app-name/MainApplication.java.

代码语言:javascript
复制
protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
            new MainReactPackage(),
            new AnExampleReactPackage()); // <-- 添加这一行,类名替换成你的Package类的名字.
}

那么在React Native中怎么使用呢?为了让你的功能从JavaScript端访问起来更为方便,通常我们都会把原生模块封装成一个JavaScript模块。

代码语言:javascript
复制
'use strict';

import { NativeModules } from 'react-native';

export default NativeModules.ToastAndroid;

最后调用javascript模块就好了。

代码语言:javascript
复制
import ToastAndroid from './ToastAndroid';
ToastAndroid.show('Awesome', ToastAndroid.SHORT);

未完待续..

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 原生模块封装
相关产品与服务
图片处理
图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档