react-native(八)引入原生Java模块

2017-11-27 00:36:06 react-native 3116 0

安卓端

生成2个文件

为了方便调试,先依据模块名生成两个文件,比如我现在要引入生成安卓的Toast组件
我的安卓项目目录是 android/app/src/main/java/com/pzshlife/sscuser/
在该目录下生成 YthModule.java 与 YthPackage.java

YthModule.java

package com.hlzblog_iot;

import android.widget.Toast;
import android.content.Context;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class YthModule extends ReactContextBaseJavaModule {
  private Context mContext;

  public YthModule(ReactApplicationContext context) {
    super(context);
    mContext = context;
  }

  @Override
  public String getName() {
    // 注:这个用于 在rn中以这个名字调用
    return "YthModule";
  }

  // 函数不能有返回值,因为被调用的原生代码是异步的,你可以照葫芦画瓢,写你在rn中调用的方法
  @ReactMethod
  public void testRn(String msg){
    Toast.makeText(mContext,msg,Toast.LENGTH_SHORT).show();
  }
}

YthPackage.java

package com.hlzblog_iot;

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;

/**
 * Created by Administrator on 2016/10/18.
 */

public class YthPackage implements ReactPackage {


    // Deprecated RN 0.47
    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 YthModule(reactContext)); // 这行引入刚刚你书写的YthModule模块

        return modules;
    }
}

修改 MainApplication.java

package com.hlzblog_iot;

import android.app.Application;

import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

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

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 YthPackage() // 引入实例化模块了的类
      );
    }
  };

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

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

编译调试

原生代码有变,需要重启npm服务,APP也需要关闭后重新进入
原生代码是否能编译成功,我们可以通过生成新Debug版本来看有没问题

react-native run-android

如果你代码写得有错误那么生成过程中就会报错
因为生成Debug是有局部缓存的,基本是直接走到编译java环节

在rn中调用写好的功能

import React, { Component } from 'react';  // 导入默认组件,与非默认组件
import {
  View,
  Text,
  NativeModules,
} from 'react-native';

export default class testScreen extends Component{
  constructor(p){
    super(p);
    console.log('testScreen -> constructor');
    if(undefined === NativeModules.YthModule ){
      console.log('YthModule未安装好');
      console.log(NativeModules); // 显示当前已编译好的模块列表
    }else{
      NativeModules.YthModule.testRn('原生调用react-native成功');
      console.log('YthModule安装成功');
    }
  }
  render(){
    return(
      <View>
        <Text>测试Rn</Text>
      </View>
    );
  }
}

好了,你可以运行一下,看看浏览器上的控制台输出的什么

标准封装

本次以我封装的 TCP 客户端功能为例

生成标准目录

进入项目根目录的 node_modules
生成 react-native-yth-tcp

生成目录结构

─android
  └─src
      └─main
          └─java
              └─com
                  └─hlzblog
                      └─react
-index.js
index.js
import {
  NativeModules
} from 'react-native';
const TCP = NativeModules.TCP; // 导出原生模块
export default TCP;
待更新
注:若无特殊说明,文章均为云天河原创,请尊重作者劳动成果,转载前请一定要注明出处