混合开发之ReactNative调用Android原生方法
16lz
2022-01-17
按照个人理解,RN和Android原生混合开发分为两种情况,第一种是以RN为主,原生为辅的混合开发,第二种则是以原生为主RN为辅的混合开发,最近几篇文章尽量以这两种情况区分,做一个大概整体的梳理
这篇文章主要讲一下以RN为主 调用Android原生函数的基本使用方法,先上图
下面看具体流程:
1,新建项目,在命令行初始化一个RN项目,这一步比较简单 就不贴图了
2、 Android原生部分代码,分三步:实现ReactContextBaseJavaModule,添加到NativeModules,Application中注册,下面看详细代码
继承ReactContextBaseJavaModule类,实现getName()方法,返回暴露给RN的模块名字,并且在这个类中实现自己需要的方法(比如下面例子中的getResult()和jumpActivity())
package com.demo2.rn_module;import android.app.Activity;import android.content.Intent;import com.demo2.SecondActivity;import com.facebook.react.bridge.ActivityEventListener;import com.facebook.react.bridge.Promise;import com.facebook.react.bridge.ReactApplicationContext;import com.facebook.react.bridge.ReactContextBaseJavaModule;import com.facebook.react.bridge.ReactMethod;public class AndroidTest extends ReactContextBaseJavaModule implements ActivityEventListener { public AndroidTest(ReactApplicationContext reactContext) { super(reactContext); } //用ReactNative注解,标示此方法是可以被RN调用的 @ReactMethod public void getResult(int a, int b, Promise promise) { int c = a + b; promise.resolve(c); } //用ReactNative注解,标示此方法是可以被RN调用的 @ReactMethod public void jumpActivity() { Intent intent = new Intent(getCurrentActivity(), SecondActivity.class); getCurrentActivity().startActivity(intent); } //返回模块名字,方便在RN中引用 @Override public String getName() { return "AndroidTest"; } //这两方法是ActivityEventListener接口中的,方便处理一些由此模块跳转后返回的回调事件 @Override public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { } @Override public void onNewIntent(Intent intent) { }}
实现ReactPackage接口,实现里面的方法,将刚才新建的AndroidTest这个Module添加到NativeModules里面
package com.demo2.rn_module;import com.facebook.react.ReactPackage;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 AndroidPackage implements ReactPackage { @Override public List createNativeModules(ReactApplicationContext reactContext) { List list = new ArrayList<>(); //添加到NativeModules AndroidTest androidTest = new AndroidTest(reactContext); list.add(androidTest); return list; } @Override public List createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); }}
继承Application并实现ReactApplication,将刚才AndroidPackage 注册到RN,如下代码:
package com.demo2;import android.app.Application;import com.demo2.rn_module.AndroidPackage;import com.facebook.react.ReactApplication;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 getPackages() { return Arrays.asList( new MainReactPackage(), new AndroidPackage() ); } @Override protected String getJSMainModuleName() { return "index"; } }; @Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; } @Override public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); }}
3、RN中的代码
新建一个AndroidConnent.js,这个JS文件就是为了导包用的,要不从引用的地方导太麻烦
import {NativeModules} from 'react-native';export default NativeModules.AndroidTest;
RN页面实现
/** * Sample React Native App * https://github.com/facebook/react-native * * @format * @flow */import React, {Component} from 'react';import {Platform, StyleSheet, Text, Button, View, Dimensions, ToastAndroid} from 'react-native';import AndroidTest from "./AndroidConnent";const ScreenWidth = Dimensions.get("window").width;const instructions = Platform.select({ ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu', android: 'Double tap R on your keyboard to reload,\n' + 'Shake or press menu button for dev menu',});type Props = {};export default class App extends Component<Props> { render() { return ( ); } onClick() { /*AndroidTest是Android原生中getName中返回的字符串*/ AndroidTest.getResult(1, 2).then(result => { ToastAndroid.show(result + "", 1000); }) } jump() { AndroidTest.jumpActivity(); }}const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, instructions: { textAlign: 'center', color: '#333333', marginBottom: 5, },});
以上就是RN中调用Android原生模块中函数的基本流程,简单的RN跳转原生界面也是一样的流程,只需要在ReactContextBaseJavaModule的子类AndroidTest中多加一个jumpActivity()方法就可以了,携带参数的情况也是一样的,最终传递参数还是在原Android原生里面传递的
还有一个Android和RN混合开发的demo,需要的可以下载参考,demo包含了
1、Android加载RN页面
2、Android调用RN函数
3、RN调用Android函数
传送门
<完>
更多相关文章
- Android中AsyncTask的简单用法
- Android(安卓)开发者从0到1发布一个微信小程序的采坑过程——使
- Android中图片实现按钮点击效果
- Android屏幕锁定实例源码详解教程一
- Android的多语言实现
- android 调用系统文件管理器
- Unity在Android和iOS中如何调用Native API (1)
- 浅谈Java中Collections.sort对List排序的两种方法
- Python list sort方法的具体使用