React native 调用Android原生模块

本文介绍了如何在React Native中调用Android原生模块。通过创建自定义的React Package,实现JavaModule类,并在MainApplication中注册,最后在JS中通过NativeModules调用来实现特定功能,如下载热更新后重启APP。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、相信使用RN 开发的同学们都会遇到这样一个问题,第三方没有支持相关的RN库,或者有一些方法在iOS上可以,但是并没有提供Android相关的方法,那么我们就只能考虑用原生去桥接第三方SDK或者自己实现相关的方法。


二、我们自己实现的方法该如何接入,在JS里面我们又是如何去调用呢?

首先自定义一个react package,我们可以叫它MyReactPackage 

/**
 * Created by jiawei.zhu on 2017/2/12.
 */
public class MyReactPackage implements ReactPackage {
  @Override
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();
    modules.add(new UpdateJsBundle(reactContext));//添加需要实现功能的JavaModule类,可以添加多个类
    return modules;
  }
  @Override
  public List<Class<? extends JavaScriptModule>> createJSModules() {
    return Collections.emptyList();
  }
  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Collections.emptyList();
  }
}


接着我们实现自定义的JavaModule类,在这里我需要实现下载热更新热bundle后重启APP.

1.继承ReactContextBaseJavaModule 类,添加功能方法restartApp

/**
 * Created by jiawei.zhu on 2017/2/12.
 */

public class UpdateJsBundle extends ReactContextBaseJavaModule {

  public static final String MODULENAME = "UpdateJsBundle";
  private Context mContext;

  public UpdateJsBundle(ReactApplicationContext reactContext) {
    super(reactContext);
    mContext = reactContext;
  }

  @Override
  public String getName() {
    return MODULENAME ;
  }

  /**
   * 必须添加注解不然会报错
   * 这个方法就是ReactNative将要调用的方法,会通过此类名字调用
   */
  @ReactMethod
  public void restartApp() {

    Intent i = getReactApplicationContext().getPackageManager()
            .getLaunchIntentForPackage(getReactApplicationContext().getPackageName());
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    mContext.startActivity(i);
  }
}


然后像第三方的库一样把实现的自定义的MyReactPackage 加到MainApplication

   @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
            new WeChatPackage(),
            new ImagePickerPackage(),
            new RNFSPackage(),
            new AlipayPackage(),
            new RCTZipPackage(),
            new RCTFileTransferPackage(),
            new MyReactPackage()//自定义
      );
    }


最后我们在JS代码里面调用自定义的UpdateJsBundle 就可以实现自己需要的功能了

引入NativeModules

import {
  Platform,
  AsyncStorage,
  NativeModules
} from 'react-native';

调用自定义JavaModule

async  checkShouldUpdate(res){
      let newSv = res.sv;
      let that = this;
      var sv = await AsyncStorage.getItem(this.svKey);
      if (!sv) {
        sv = '0';
      }
      console.log("newSv ,old sv",newSv,sv);


      if (NumberUtil.compareVersionNum(newSv,sv)>0) {
          console.log("进行加载新包 地址是 re.svurl",res.svurl);
          let fileHeadPath  = Platform.OS=='ios'?RNFS.LibraryDirectoryPath:RNFS.ExternalDirectoryPath;
          let fileTialPath = '/tempjsbundle/'+newSv+'tempjsbundle.zip';
          var downzippath = fileHeadPath + fileTialPath;
          console.log("downzippath",downzippath);
          // Platform.OS=='ios'?'/client/tempfolder/tempjsbundle.zip':'/sdcard/data/tempfolder/tempjsbundle.zip'
          var fileTransfer = new FileTransfer();
          var uri = encodeURI(res.svurl);
          fileTransfer.onprogress = (progress) => console.log("1",progress.loaded+'/'+progress.total);
          fileTransfer.download(
              uri,
              downzippath,
              function(result) {
                  console.log(result);


                  var downJsBundlePath = fileHeadPath + '/downjsbundle/';
                  console.log("downJsBundlePath",downJsBundlePath);


                  Zip.unzip(downzippath, downJsBundlePath, (err)=>{
                    if (err) {
                      console.log("解压失败");
                    } else {
                      NativeModules.UpdateJsBundle.restartApp();//调用自定义JavaModule
                      console.log("解压成功,将zip删除");

                      let nowTime = (new Date()).valueOf();
                      that.saveCheckTime(nowTime);
                      that.saveSV(newSv);
                      console.log("保存newsv,time",newSv,nowTime);
                      RNFS.unlink(downzippath).then(() => {
                        // 通过解压得到的补丁文件生成最新版的jsBundle
                      });
                    }
                  });
              },
              function(error) {
                  console.log("下载失败");
                  console.log(error);
              },


          );
      }else{
        console.log("sv版本已经是最高")
      }
  }


总结:实现js调用原生模块有4个步奏

(1)自定义MyReactPackage继承ReactPackage ,并在createNativeModules方法内添加自己需要实现的类 modules.add(new UpdateJsBundle(reactContext));//添加需要实现功能的JavaModule类,可以添加多个类。

(2)实现自定义的UpdateJsBundle,继承ReactContextBaseJavaModule 实现功能方法restartApp该方法必须添加@ReactMethod注解。

(3)在MainApplication引入MyReactPackage

(4)JS通过NativeModules调用NativeModules.UpdateJsBundle.restartApp();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值