1 问题
实现js调用安卓原始代码,直接上代码,简单粗暴
2 代码实现
1) 实现一个继承ReactContextBaseJavaModule的类,MyToastModule.java文件如下
public class MyToastModule extends ReactContextBaseJavaModule { public MyToastModule(ReactApplicationContext reactContext) { super(reactContext); } /** * getName方法返回一个字符串名字,就是js中的模块名 * 到时候我们写js的时候需要导入这个模块,这里我用的是MyToast */ @Override public String getName() { return "MyToast"; } /** * 这是js调用的方法,需要使用注解@ReactMethod,返回类型必须为void */ @ReactMethod public void show() { Toast.makeText(getReactApplicationContext(), "I am chenyu", Toast.LENGTH_SHORT).show(); } }
getName()方法返回一个字符串名字,就是js中的模块名,到时候我们写js的时候需要导入这个模块,这里我用的是MyToastshow()方法 show()方法是到时候js调用的方法,需要使用注解@ReactMethod,返回类型必须为void
2) 实现继承ReactPackage的一个类
MyToastReactPackage.java 文件如下
package com.pro_react; 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 MyToastReactPackage implements ReactPackage { /** * 需要在应用的Package类的createNativeModules方法中添加这个模块。 * 如果模块没有被注册,它也无法在JavaScript中被访问到。 * @param reactContext * @return */ @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); modules.add(new MyToastModule(reactContext)); return modules; } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } }
这里的createNativeModules方法需要添加我之前写的MyToastModule模块
3 ) 在MainApplication.java文加的getPackages方法中添加我自己的包,代码如下
package com.pro_react; import android.app.AppOpsManager; import android.app.Application; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.net.Uri; import android.os.Build; import android.util.Log; 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.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; public class MainApplication extends Application implements ReactApplication { public static final String TAG = "MainApplication"; private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List<ReactPackage> getPackages() { Log.i(TAG, "MainApplication getPackages"); return Arrays.<ReactPackage>asList( new MainReactPackage(), new MyToastReactPackage() ); } @Override protected String getJSMainModuleName() { return "index"; } }; @Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; } @Override public void onCreate() { super.onCreate(); Log.i(TAG, "MainApplication onCreate"); SoLoader.init(this, /* native exopackage */ false); } }
4) js模块的编写
js模块要注意你需要加入这个
import {NativeModules} from 'react-native'
然后用变量保存安卓的模块,也就是上面getName方法里面的返回值MyToast
var myAndroidToast = NativeModules.MyToast;
然后我是模拟,文本点击触发的调用原声安卓的函数,App.js文件如下
/** * Sample React Native App * https://github.com/facebook/react-native * * @format * @flow */ import React, {Component} from 'react'; import {Platform, StyleSheet, Text, View, NativeModules} from 'react-native'; 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', }); var myAndroidToast = NativeModules.MyToast; type Props = {}; export default class App extends Component<Props> { render() { return ( <View style={styles.container}> <Text onPress={()=> this._androidShowMsg()} style={styles.welcome}>Welcome to React Native!</Text> <Text style={styles.instructions}>To get started, edit App.js</Text> <Text style={styles.instructions}>{instructions}</Text> </View> ); } /** *调用安卓原生代码 * @private */ _androidShowMsg = () => { myAndroidToast.show(); }; } 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, }, });
3 运行结果
运行之前要记得在项目的目录下执行下面的命令,它会在android的assets目录下生成index.android.bundle文件,也就是安卓会加载这个js文件,这里也会起到编译js作用,如果有语法错误,这里控制台会提示
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res
然后执行运行项目命令
react-native run-android
点击Welcome to React Native运行结果如下